[jboss-cvs] JBoss Messaging SVN: r2796 - in trunk: docs/examples/common/src/org/jboss/example/jms/common and 61 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Jun 25 18:24:43 EDT 2007


Author: timfox
Date: 2007-06-25 18:24:41 -0400 (Mon, 25 Jun 2007)
New Revision: 2796

Added:
   trunk/src/etc/server/default/deploy/db2-persistence-service.xml
   trunk/src/etc/server/default/deploy/mssql-persistence-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/MessagingPostOffice-xmbean.xml
   trunk/src/main/org/jboss/jms/client/container/ClientConsumer.java
   trunk/src/main/org/jboss/messaging/core/contract/
   trunk/src/main/org/jboss/messaging/core/contract/Binding.java
   trunk/src/main/org/jboss/messaging/core/contract/Channel.java
   trunk/src/main/org/jboss/messaging/core/contract/ClusterNotification.java
   trunk/src/main/org/jboss/messaging/core/contract/ClusterNotificationListener.java
   trunk/src/main/org/jboss/messaging/core/contract/ClusterNotifier.java
   trunk/src/main/org/jboss/messaging/core/contract/Condition.java
   trunk/src/main/org/jboss/messaging/core/contract/ConditionFactory.java
   trunk/src/main/org/jboss/messaging/core/contract/Delivery.java
   trunk/src/main/org/jboss/messaging/core/contract/DeliveryObserver.java
   trunk/src/main/org/jboss/messaging/core/contract/Distributor.java
   trunk/src/main/org/jboss/messaging/core/contract/FailoverMapper.java
   trunk/src/main/org/jboss/messaging/core/contract/Filter.java
   trunk/src/main/org/jboss/messaging/core/contract/FilterFactory.java
   trunk/src/main/org/jboss/messaging/core/contract/JChannelFactory.java
   trunk/src/main/org/jboss/messaging/core/contract/MemoryManager.java
   trunk/src/main/org/jboss/messaging/core/contract/Message.java
   trunk/src/main/org/jboss/messaging/core/contract/MessageReference.java
   trunk/src/main/org/jboss/messaging/core/contract/MessageStore.java
   trunk/src/main/org/jboss/messaging/core/contract/MessagingComponent.java
   trunk/src/main/org/jboss/messaging/core/contract/PersistenceManager.java
   trunk/src/main/org/jboss/messaging/core/contract/PostOffice.java
   trunk/src/main/org/jboss/messaging/core/contract/Queue.java
   trunk/src/main/org/jboss/messaging/core/contract/Receiver.java
   trunk/src/main/org/jboss/messaging/core/contract/Replicator.java
   trunk/src/main/org/jboss/messaging/core/impl/
   trunk/src/main/org/jboss/messaging/core/impl/ChannelSupport.java
   trunk/src/main/org/jboss/messaging/core/impl/ClusterRoundRobinDistributor.java
   trunk/src/main/org/jboss/messaging/core/impl/DefaultClusterNotifier.java
   trunk/src/main/org/jboss/messaging/core/impl/FailoverWaiter.java
   trunk/src/main/org/jboss/messaging/core/impl/FirstReceiverDistributor.java
   trunk/src/main/org/jboss/messaging/core/impl/IDManager.java
   trunk/src/main/org/jboss/messaging/core/impl/JDBCPersistenceManager.java
   trunk/src/main/org/jboss/messaging/core/impl/JDBCSupport.java
   trunk/src/main/org/jboss/messaging/core/impl/MessagingQueue.java
   trunk/src/main/org/jboss/messaging/core/impl/PagingChannelSupport.java
   trunk/src/main/org/jboss/messaging/core/impl/RoundRobinDistributor.java
   trunk/src/main/org/jboss/messaging/core/impl/SimpleDelivery.java
   trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/
   trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/MultiplexerJChannelFactory.java
   trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/XMLJChannelFactory.java
   trunk/src/main/org/jboss/messaging/core/impl/memory/
   trunk/src/main/org/jboss/messaging/core/impl/memory/SimpleMemoryManager.java
   trunk/src/main/org/jboss/messaging/core/impl/plugin/
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/BindRequest.java
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/ClusterRequest.java
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/DefaultFailoverMapper.java
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/GroupListener.java
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/GroupMember.java
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/LeaveClusterRequest.java
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/MappingInfo.java
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/MessageHolder.java
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/MessageRequest.java
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/MessagingPostOffice.java
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/PostOfficeAddressInfo.java
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/PutReplicantRequest.java
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/RemoveReplicantRequest.java
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/RequestTarget.java
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/SharedState.java
   trunk/src/main/org/jboss/messaging/core/impl/postoffice/UnbindRequest.java
   trunk/src/main/org/jboss/messaging/core/impl/tx/
   trunk/src/main/org/jboss/messaging/core/impl/tx/PreparedTxInfo.java
   trunk/src/main/org/jboss/messaging/core/impl/tx/Transaction.java
   trunk/src/main/org/jboss/messaging/core/impl/tx/TransactionException.java
   trunk/src/main/org/jboss/messaging/core/impl/tx/TransactionRepository.java
   trunk/src/main/org/jboss/messaging/core/impl/tx/TxCallback.java
   trunk/src/main/org/jboss/messaging/core/jmx/
   trunk/src/main/org/jboss/messaging/core/jmx/JDBCMBeanSupport.java
   trunk/src/main/org/jboss/messaging/core/jmx/JDBCPersistenceManagerService.java
   trunk/src/main/org/jboss/messaging/core/jmx/JDBCServiceSupport.java
   trunk/src/main/org/jboss/messaging/core/jmx/MessagingPostOfficeService.java
   trunk/src/main/org/jboss/messaging/util/LockMap.java
   trunk/tests/src/org/jboss/test/messaging/core/IdManagerTest.java
   trunk/tests/src/org/jboss/test/messaging/core/JDBCPersistenceManagerTest.java
   trunk/tests/src/org/jboss/test/messaging/core/JDBCUtilTest.java
   trunk/tests/src/org/jboss/test/messaging/core/MessageStoreTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/MessagingQueueTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/NonRecoverableMessagingQueueTest.java
   trunk/tests/src/org/jboss/test/messaging/core/PostOfficeTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/RecoverableMessagingQueueTest.java
   trunk/tests/src/org/jboss/test/messaging/core/RoundRobinDistributorTest.java
   trunk/tests/src/org/jboss/test/messaging/core/SimpleMessageStoreTest.java
   trunk/tests/src/org/jboss/test/messaging/core/message/MessageSupportTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/paging/PagingStateTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/ClusteredPersistenceServiceConfigFileJChannelFactory.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/ClusteredPostOfficeTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/DefaultClusteredPostOfficeWithDefaultRouterTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/PostOfficeTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/SimpleJChannelFactory.java
Removed:
   trunk/src/etc/server/default/deploy/clustered-db2-persistence-service.xml
   trunk/src/etc/server/default/deploy/clustered-mssql-persistence-service.xml
   trunk/src/etc/server/default/deploy/clustered-mysql-persistence-service.xml
   trunk/src/etc/server/default/deploy/clustered-oracle-persistence-service.xml
   trunk/src/etc/server/default/deploy/clustered-postgresql-persistence-service.xml
   trunk/src/etc/server/default/deploy/clustered-sybase-persistence-service.xml
   trunk/src/etc/server/default/deploy/db2-persistence-service.xml
   trunk/src/etc/server/default/deploy/mssql-persistence-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/ClusteredPostOffice-xmbean.xml
   trunk/src/etc/xmdesc/DefaultPostOffice-xmbean.xml
   trunk/src/main/org/jboss/jms/client/remoting/MessageCallbackHandler.java
   trunk/src/main/org/jboss/jms/server/ServerPeerMBean.java
   trunk/src/main/org/jboss/messaging/core/Channel.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/DeliveryObserver.java
   trunk/src/main/org/jboss/messaging/core/Distributor.java
   trunk/src/main/org/jboss/messaging/core/Filter.java
   trunk/src/main/org/jboss/messaging/core/FilterFactory.java
   trunk/src/main/org/jboss/messaging/core/PagingChannelSupport.java
   trunk/src/main/org/jboss/messaging/core/Queue.java
   trunk/src/main/org/jboss/messaging/core/Receiver.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/impl/jchannelfactory/JChannelFactory.java
   trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/MultiplexerJChannelFactory.java
   trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/XMLJChannelFactory.java
   trunk/src/main/org/jboss/messaging/core/impl/memory/MemoryManager.java
   trunk/src/main/org/jboss/messaging/core/impl/memory/SimpleMemoryManager.java
   trunk/src/main/org/jboss/messaging/core/impl/tx/PreparedTxInfo.java
   trunk/src/main/org/jboss/messaging/core/impl/tx/Transaction.java
   trunk/src/main/org/jboss/messaging/core/impl/tx/TransactionException.java
   trunk/src/main/org/jboss/messaging/core/impl/tx/TransactionRepository.java
   trunk/src/main/org/jboss/messaging/core/impl/tx/TxCallback.java
   trunk/src/main/org/jboss/messaging/core/local/FirstReceiverPointToPointRouter.java
   trunk/src/main/org/jboss/messaging/core/local/PagingFilteredQueue.java
   trunk/src/main/org/jboss/messaging/core/local/RoundRobinPointToPointRouter.java
   trunk/src/main/org/jboss/messaging/core/memory/
   trunk/src/main/org/jboss/messaging/core/message/CoreMessage.java
   trunk/src/main/org/jboss/messaging/core/message/Message.java
   trunk/src/main/org/jboss/messaging/core/message/MessageFactory.java
   trunk/src/main/org/jboss/messaging/core/message/MessageHolder.java
   trunk/src/main/org/jboss/messaging/core/message/MessageReference.java
   trunk/src/main/org/jboss/messaging/core/message/MessageSupport.java
   trunk/src/main/org/jboss/messaging/core/message/SimpleMessageReference.java
   trunk/src/main/org/jboss/messaging/core/message/SimpleMessageStore.java
   trunk/src/main/org/jboss/messaging/core/plugin/ClusteredPostOfficeService.java
   trunk/src/main/org/jboss/messaging/core/plugin/DefaultPostOfficeService.java
   trunk/src/main/org/jboss/messaging/core/plugin/IDManager.java
   trunk/src/main/org/jboss/messaging/core/plugin/JDBCMBeanSupport.java
   trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManager.java
   trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManagerService.java
   trunk/src/main/org/jboss/messaging/core/plugin/JDBCServiceSupport.java
   trunk/src/main/org/jboss/messaging/core/plugin/JDBCSupport.java
   trunk/src/main/org/jboss/messaging/core/plugin/LockMap.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/ClusteredPostOffice.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/Condition.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/ConditionFactory.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/FailoverMapper.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/MessageStore.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/MessagingComponent.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/MessagingService.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/PostOffice.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/ReplicationListener.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/Replicator.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/ServerPlugin.java
   trunk/src/main/org/jboss/messaging/core/plugin/postoffice/Binding.java
   trunk/src/main/org/jboss/messaging/core/plugin/postoffice/Bindings.java
   trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultBinding.java
   trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultBindings.java
   trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultPostOffice.java
   trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/
   trunk/src/main/org/jboss/messaging/core/tx/
   trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryTest.java
   trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverablePagingFilteredQueueTest.java
   trunk/tests/src/org/jboss/test/messaging/core/local/RecoverablePagingFilteredQueueTest.java
   trunk/tests/src/org/jboss/test/messaging/core/local/RoundRobinPointToPointRouterTest.java
   trunk/tests/src/org/jboss/test/messaging/core/local/base/PagingFilteredQueueTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/message/base/RoutableSupportTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/paging/base/PagingStateTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/persistence/JDBCUtilTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/IdManagerTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/SimpleMessageStoreTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/base/MessageStoreTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/base/PostOfficeTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/DefaultPostOfficeTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/ClusteredPersistenceServiceConfigFileJChannelFactory.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/ClusteredPostOfficeConfigurationTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeWithDefaultRouterTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeWithRoundRobinRouterTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultMessagePullPolicyTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultRouterTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/FailoverMapperTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RecoveryTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RedistributionWithDefaultMessagePullPolicyTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RoundRobinRouterTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/SimpleJChannelFactory.java
   trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueTest.java
Modified:
   trunk/.classpath
   trunk/build-messaging.xml
   trunk/build-thirdparty.xml
   trunk/docs/examples/common/src/org/jboss/example/jms/common/Util.java
   trunk/docs/examples/distributed-queue/src/org/jboss/example/jms/distributedqueue/DistributedQueueExample.java
   trunk/src/etc/server/default/deploy/connection-factories-service.xml
   trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml
   trunk/src/etc/server/default/deploy/messaging-service.xml
   trunk/src/etc/xmdesc/Bridge-xmbean.xml
   trunk/src/etc/xmdesc/JDBCPersistenceManager-xmbean.xml
   trunk/src/etc/xmdesc/JMSUserManager-xmbean.xml
   trunk/src/etc/xmdesc/Queue-xmbean.xml
   trunk/src/etc/xmdesc/ServerPeer-xmbean.xml
   trunk/src/etc/xmdesc/Topic-xmbean.xml
   trunk/src/main/org/jboss/jms/client/JBossConnection.java
   trunk/src/main/org/jboss/jms/client/JBossConnectionConsumer.java
   trunk/src/main/org/jboss/jms/client/JBossSession.java
   trunk/src/main/org/jboss/jms/client/container/ClusteringAspect.java
   trunk/src/main/org/jboss/jms/client/container/ConsumerAspect.java
   trunk/src/main/org/jboss/jms/client/container/SessionAspect.java
   trunk/src/main/org/jboss/jms/client/container/StateCreationAspect.java
   trunk/src/main/org/jboss/jms/client/delegate/ClientClusteredConnectionFactoryDelegate.java
   trunk/src/main/org/jboss/jms/client/delegate/ClientSessionDelegate.java
   trunk/src/main/org/jboss/jms/client/remoting/CallbackManager.java
   trunk/src/main/org/jboss/jms/client/state/ConsumerState.java
   trunk/src/main/org/jboss/jms/client/state/SessionState.java
   trunk/src/main/org/jboss/jms/delegate/DeliveryInfo.java
   trunk/src/main/org/jboss/jms/delegate/SessionDelegate.java
   trunk/src/main/org/jboss/jms/delegate/SessionEndpoint.java
   trunk/src/main/org/jboss/jms/destination/JBossDestination.java
   trunk/src/main/org/jboss/jms/destination/JBossQueue.java
   trunk/src/main/org/jboss/jms/message/JBossMessage.java
   trunk/src/main/org/jboss/jms/server/ConnectionFactoryManager.java
   trunk/src/main/org/jboss/jms/server/ConnectionManager.java
   trunk/src/main/org/jboss/jms/server/ConnectorManager.java
   trunk/src/main/org/jboss/jms/server/DestinationManager.java
   trunk/src/main/org/jboss/jms/server/JMSCondition.java
   trunk/src/main/org/jboss/jms/server/JMSConditionFactory.java
   trunk/src/main/org/jboss/jms/server/ServerPeer.java
   trunk/src/main/org/jboss/jms/server/bridge/Bridge.java
   trunk/src/main/org/jboss/jms/server/bridge/BridgeService.java
   trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactory.java
   trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactoryJNDIMapper.java
   trunk/src/main/org/jboss/jms/server/destination/DestinationServiceSupport.java
   trunk/src/main/org/jboss/jms/server/destination/ManagedDestination.java
   trunk/src/main/org/jboss/jms/server/destination/ManagedQueue.java
   trunk/src/main/org/jboss/jms/server/destination/ManagedTopic.java
   trunk/src/main/org/jboss/jms/server/destination/QueueService.java
   trunk/src/main/org/jboss/jms/server/destination/TopicService.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/server/endpoint/advised/SessionAdvised.java
   trunk/src/main/org/jboss/jms/server/messagecounter/MessageCounter.java
   trunk/src/main/org/jboss/jms/server/messagecounter/MessageCounterManager.java
   trunk/src/main/org/jboss/jms/server/plugin/JDBCJMSUserManager.java
   trunk/src/main/org/jboss/jms/server/plugin/JDBCJMSUserManagerService.java
   trunk/src/main/org/jboss/jms/server/plugin/contract/JMSUserManager.java
   trunk/src/main/org/jboss/jms/server/selector/Selector.java
   trunk/src/main/org/jboss/jms/server/selector/SelectorFactory.java
   trunk/src/main/org/jboss/jms/tx/ClientTransaction.java
   trunk/src/main/org/jboss/jms/tx/ResourceManager.java
   trunk/src/main/org/jboss/jms/wireformat/BrowserNextMessageBlockResponse.java
   trunk/src/main/org/jboss/jms/wireformat/BrowserNextMessageResponse.java
   trunk/src/main/org/jboss/jms/wireformat/ClientDelivery.java
   trunk/src/main/org/jboss/jms/wireformat/SessionCreateConsumerDelegateRequest.java
   trunk/src/main/org/jboss/jms/wireformat/SessionSendRequest.java
   trunk/tests/build.xml
   trunk/tests/src/org/jboss/test/messaging/core/BrokenReceiver.java
   trunk/tests/src/org/jboss/test/messaging/core/SimpleChannel.java
   trunk/tests/src/org/jboss/test/messaging/core/SimpleCondition.java
   trunk/tests/src/org/jboss/test/messaging/core/SimpleConditionFactory.java
   trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryObserver.java
   trunk/tests/src/org/jboss/test/messaging/core/SimpleFilter.java
   trunk/tests/src/org/jboss/test/messaging/core/SimpleFilterFactory.java
   trunk/tests/src/org/jboss/test/messaging/core/SimpleReceiver.java
   trunk/tests/src/org/jboss/test/messaging/core/message/CoreMessageTest.java
   trunk/tests/src/org/jboss/test/messaging/core/message/JBossMessageTest.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/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/jms/AcknowledgementTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/DLQTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/ExpiryQueueTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/MessageCleanupTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/PersistenceTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/ReferencingTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/WireFormatTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/clustering/ClusterEventNotificationListener.java
   trunk/tests/src/org/jboss/test/messaging/jms/clustering/ClusterViewUpdateTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedDestinationsTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/clustering/GroupManagementTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/clustering/RequestResponseWithPullTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/clustering/base/ClusteringTestBase.java
   trunk/tests/src/org/jboss/test/messaging/jms/persistence/BytesMessagePersistenceManagerTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/persistence/MapMessagePersistenceManagerTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/persistence/MessagePersistenceManagerTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/persistence/ObjectMessagePersistenceManagerTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/persistence/StreamMessagePersistenceManagerTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/persistence/TextMessagePersistenceManagerTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/server/ServerPeerTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/server/destination/QueueManagementTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/server/destination/TopicManagementTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/stress/base/StressTestBase.java
   trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java
   trunk/tests/src/org/jboss/test/messaging/tools/jmx/ServiceContainer.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
   trunk/tests/src/org/jboss/test/messaging/util/CoreMessageFactory.java
Log:
Some refactoring to core and message pull refactoring - partial completion


Modified: trunk/.classpath
===================================================================
--- trunk/.classpath	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/.classpath	2007-06-25 22:24:41 UTC (rev 2796)
@@ -19,19 +19,7 @@
 	<classpathentry kind="src" path="docs/examples/topic/src"/>
 	<classpathentry excluding="**/.svn/**/*" kind="src" path="src/main"/>
 	<classpathentry excluding="**/.svn/**/*" kind="src" path="tests/src"/>
-	<classpathentry kind="lib" path="lib/jboss.jar"/>
-	<classpathentry kind="lib" path="lib/jboss-j2ee.jar"/>
-	<classpathentry kind="lib" path="lib/jboss-jmx.jar"/>
-	<classpathentry kind="lib" path="lib/jbosssx.jar"/>
-	<classpathentry kind="lib" path="lib/jboss-system.jar"/>
-	<classpathentry kind="lib" path="lib/jboss-transaction.jar"/>
-	<classpathentry kind="lib" path="lib/jnp-client.jar"/>
 	<classpathentry kind="lib" path="thirdparty/oswego-concurrent/lib/concurrent.jar"/>
-	<classpathentry kind="lib" path="tests/lib/jboss-common-jdbc-wrapper.jar"/>
-	<classpathentry kind="lib" path="tests/lib/jboss-jca.jar"/>
-	<classpathentry kind="lib" path="tests/lib/jboss-local-jdbc.jar"/>
-	<classpathentry kind="lib" path="tests/lib/jboss-mbeans.jar"/>
-	<classpathentry kind="lib" path="tests/lib/jms-ra.jar"/>
 	<classpathentry kind="lib" path="thirdparty/jgroups/lib/jgroups.jar"/>
 	<classpathentry kind="lib" path="thirdparty/apache-log4j/lib/log4j.jar"/>
 	<classpathentry kind="lib" path="thirdparty/junit/lib/junit.jar"/>
@@ -45,8 +33,6 @@
 	<classpathentry kind="lib" path="thirdparty/dom4j/lib/dom4j.jar"/>
 	<classpathentry kind="lib" path="thirdparty/javassist/lib/javassist.jar"/>
 	<classpathentry kind="lib" path="thirdparty/jboss/aop/lib/common-softvaluehashmap.jar"/>
-	<classpathentry kind="lib" path="thirdparty/jboss/aop/lib/jboss-aop-jdk50.jar"/>
-	<classpathentry kind="lib" path="thirdparty/jboss/aop/lib/jboss-aop-jdk50-client.jar"/>
 	<classpathentry kind="lib" path="thirdparty/jboss/aop/lib/jdk14-pluggable-instrumentor.jar"/>
 	<classpathentry kind="lib" path="thirdparty/jboss/aop/lib/jrockit-pluggable-instrumentor.jar"/>
 	<classpathentry kind="lib" path="thirdparty/jboss/aop/lib/pluggable-instrumentor.jar"/>
@@ -61,6 +47,19 @@
 	<classpathentry kind="var" path="ANT_HOME/lib/ant-junit.jar"/>
 	<classpathentry kind="lib" path="thirdparty/jboss/common/lib/jboss-common.jar"/>
 	<classpathentry kind="src" path=".apt_generated"/>
-	<classpathentry kind="lib" path="lib/jboss-j2se.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jbossas/core-libs/lib/jboss-j2ee.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jboss/aop/lib/jboss-aop.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jbossas/core-libs/lib/jboss-system.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jbossas/core-libs/lib/jboss-jmx.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jbossas/core-libs/lib/jboss-transaction-client.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jbossas/core-libs/lib/jbosssx-client.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jbossas/core-libs/lib/jboss.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jbossas/core-libs/lib/jms-ra.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jbossas/core-libs/lib/jboss-common.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jbossas/core-libs/lib/jboss-common-jdbc-wrapper.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jbossas/core-libs/lib/jbosscx-client.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jbossas/core-libs/lib/jboss-jca.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jbossas/core-libs/lib/jboss-local-jdbc.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jbossas/core-libs/lib/jboss-xml-binding.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>

Modified: trunk/build-messaging.xml
===================================================================
--- trunk/build-messaging.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/build-messaging.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -165,37 +165,10 @@
       <path refid="jboss.serialization.classpath"/>
    </path>
 
-   <path id="jboss.transaction.classpath">
-      <pathelement location="${project.root}/lib/jboss-transaction.jar"/>
-   </path>
-
    <!--
-       If I don't use directly UnifiedClassLoader3, this should go away.
-   -->
-   <path id="jboss.jmx.classpath">
-      <pathelement location="${project.root}/lib/jboss-jmx.jar"/>
-   </path>
-
-   <!--
-       This is for compiling the JBossAS JBossTS driven JMS recovery code which uses XAResourceWrapper implementation
-   -->
-   <path id="jboss.classpath">
-      <pathelement location="${project.root}/lib/jboss.jar"/>
-   </path>
-
-   <property name="jboss.server.lib" value="${project.root}/lib/"/>
-
-   <property name="jboss.naming.lib" value="${project.root}/lib/"/>
-
-   <path id="local.dependencies.classpath">
-      <path refid="jboss.classpath"/>
-   </path>
-
-   <!--
         The compilation classpath.
    -->
    <path id="compilation.classpath">
-      <path refid="local.dependencies.classpath"/>
       <path refid="external.dependencies.classpath"/>
       <path refid="jboss.dependencies.classpath"/>
    </path>

Modified: trunk/build-thirdparty.xml
===================================================================
--- trunk/build-thirdparty.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/build-thirdparty.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -91,7 +91,6 @@
       <componentref name="jboss/aop" version="1.5.5.GA"/>
       <componentref name="jboss/remoting" version="2.2.0.SP4"/>
       <componentref name="jboss/jbossts14" version="4.2.3.SP3"/>
-      <componentref name="jboss/jbossts14" version="4.2.3.SP3"/>
       <componentref name="jbossas/core-libs" version="4.2.0.GA"/>
 
 

Modified: trunk/docs/examples/common/src/org/jboss/example/jms/common/Util.java
===================================================================
--- trunk/docs/examples/common/src/org/jboss/example/jms/common/Util.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/docs/examples/common/src/org/jboss/example/jms/common/Util.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -67,34 +67,6 @@
        deployQueue(jndiName,null);
    }
 
-   // TODO: NOT TESTED!
-   public static void activateMessagePullPolicy(InitialContext ic) throws Exception
-   {
-      // Need to promgrammatically activate the default message pull policy.
-      
-      // We need to do this here since the default config ships with the NullMessagePullPolicy which
-      // doesn't do message redistribution.
-      
-      // You won't have to do this in your own programs - you just need to make sure your postoffice
-      // MBean config specifies the DefaultMessagePullPolicy
-      
-      MBeanServerConnection mBeanServer = lookupMBeanServerProxy(ic);
-      
-      ObjectName postOfficeObjectName = new ObjectName("jboss.messaging:service=PostOffice");
-
-      mBeanServer.invoke(postOfficeObjectName, "stop", null, null);
-      
-      Attribute att =
-         new Attribute("MessagePullPolicy",
-                       "org.jboss.messaging.core.plugin.postoffice.cluster.NullMessagePullPolicy");
-      
-      mBeanServer.setAttribute(postOfficeObjectName, att);
-
-      // Restart the post office
-      
-      mBeanServer.invoke(postOfficeObjectName, "start", null, null);
-   }
-
    public static void deployQueue(String jndiName, InitialContext ic) throws Exception
    {
       MBeanServerConnection mBeanServer = lookupMBeanServerProxy(ic);

Modified: trunk/docs/examples/distributed-queue/src/org/jboss/example/jms/distributedqueue/DistributedQueueExample.java
===================================================================
--- trunk/docs/examples/distributed-queue/src/org/jboss/example/jms/distributedqueue/DistributedQueueExample.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/docs/examples/distributed-queue/src/org/jboss/example/jms/distributedqueue/DistributedQueueExample.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -37,10 +37,6 @@
  * The example creates two connections to two distinct cluster nodes on which we have previously
  * deployed a distributed queue. The example sends and receives messages using both connections.
  *
- * NOTE: This is an example that assumes a NullMessagePullPolicy. This is the default configuration
- *       option a release ships with, and also is a very boring options, since messages are *NOT*
- *       redistributed among nodes. An example that assumes a DefaultMessagePullPolicy is coming
- *       soon (http://jira.jboss.org/jira/browse/JBMESSAGING-907).
  *
  * Since this example is also used as a smoke test, it is essential that the VM exits with exit
  * code 0 in case of successful execution and a non-zero value on failure.
@@ -116,9 +112,6 @@
 
          log("The messages were successfully sent to the distributed queue");
 
-         // NOTE: We know that this example is extremely boring, but so it's NullMessagePullPolicy.
-         //       However, this is the default configuration option a release ships with.
-
          messageListener0.waitForMessage(3000);
 
          message = (TextMessage)messageListener0.getMessage();

Deleted: trunk/src/etc/server/default/deploy/clustered-db2-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/clustered-db2-persistence-service.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/server/default/deploy/clustered-db2-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,155 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-     DB2 clustered persistence deployment descriptor.
-
-     UNTESTED
-
-     $Id$
- -->
-
-<server>
-
-   <mbean code="org.jboss.messaging.core.plugin.JDBCPersistenceManagerService"
-      name="jboss.messaging:service=PersistenceManager"
-      xmbean-dd="xmdesc/JDBCPersistenceManager-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="UsingBatchUpdates">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, DELIVERY_COUNT INTEGER, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
-   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
-   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
-   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
-   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
-   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
-   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY SMALLINT, HEADERS BLOB, PAYLOAD BLOB, CHANNEL_COUNT INTEGER, TYPE SMALLINT, PRIMARY KEY (MESSAGE_ID))
-   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID BIGINT, BRANCH_QUAL BLOB(254), FORMAT_ID INTEGER, GLOBAL_TXID BLOB(254), PRIMARY KEY (TRANSACTION_ID))
-   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))
-   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
-   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
-   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
-   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
-   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
-   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
-   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
-   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
-   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
-   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
-   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
-   SELECT_EXISTS_REF=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
-   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
-   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
-   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
-   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
-   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
-   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
-   MESSAGE_ID_COLUMN=MESSAGE_ID
-   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ? FOR UPDATE
-   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
-   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
-   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
-   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
-   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
-   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
-   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=? FOR UPDATE
-   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
-   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
-      ]]></attribute>
-      <attribute name="MaxParams">500</attribute>
-   </mbean>
-
-   <mbean code="org.jboss.messaging.core.plugin.ClusteredPostOfficeService"
-      name="jboss.messaging:service=PostOffice"
-      xmbean-dd="xmdesc/ClusteredPostOffice-xmbean.xml">
-      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
-      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-      <attribute name="PostOfficeName">Clustered JMS</attribute>
-      <attribute name="DataSource">java:/DefaultDS</attribute>
-      <attribute name="CreateTablesOnStartup">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID INTEGER, QUEUE_NAME VARCHAR(1023), COND VARCHAR(1023), SELECTOR VARCHAR(1023), CHANNEL_ID BIGINT, CLUSTERED CHAR(1))
-INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
-DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
-LOAD_BINDINGS=SELECT NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME  = ?
-      ]]></attribute>
-      <attribute name="GroupName">DefaultPostOffice</attribute>
-      <attribute name="StateTimeout">5000</attribute>
-      <attribute name="CastTimeout">5000</attribute>
-      <attribute name="StatsSendPeriod">3000</attribute>
-      <attribute name="MessagePullPolicy">org.jboss.messaging.core.plugin.postoffice.cluster.NullMessagePullPolicy</attribute>
-      <attribute name="ClusterRouterFactory">org.jboss.messaging.core.plugin.postoffice.cluster.DefaultRouterFactory</attribute>
-
-
-      <attribute name="ChannelFactoryName">jgroups.mux:name=Multiplexer</attribute>
-      <attribute name="SyncChannelName">udp-sync</attribute>
-      <attribute name="AsyncChannelName">udp</attribute>
-      <attribute name="ChannelPartitionName">${jboss.partition.name:DefaultPartition}-JMS</attribute>
-
-      <attribute name="AsyncChannelConfig">
-         <config>
-            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
-           mcast_port="45567" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
-           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
-            <AUTOCONF down_thread="false" up_thread="false"/>
-            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
-            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
-            <FD_SOCK down_thread="false" up_thread="false"/>
-            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
-            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
-            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
-                         retransmit_timeout="100,200,600,1200,2400,4800"/>
-            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
-            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
-            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
-            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
-            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
-         </config>
-      </attribute>
-
-      <attribute name="SyncChannelConfig">
-         <config>
-            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
-           mcast_port="45568" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
-           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
-            <AUTOCONF down_thread="false" up_thread="false"/>
-            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
-            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
-            <FD_SOCK down_thread="false" up_thread="false"/>
-            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
-            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
-            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
-                         retransmit_timeout="100,200,600,1200,2400,4800"/>
-            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
-            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
-            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
-            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
-            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
-            <pbcast.STATE_TRANSFER down_thread="false" up_thread="false"/>
-         </config>
-      </attribute>
-   </mbean>
-
-   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
-      name="jboss.messaging:service=JMSUserManager"
-      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
-CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
-SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
-      ]]></attribute>
-   </mbean>
-
-</server>
\ No newline at end of file

Deleted: trunk/src/etc/server/default/deploy/clustered-mssql-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/clustered-mssql-persistence-service.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/server/default/deploy/clustered-mssql-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,155 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-     MS SQL Server clustered persistence deployment descriptor.
-
-     Tested with SQL Server 2005
-
-     $Id$
- -->
-
-<server>
-
-   <mbean code="org.jboss.messaging.core.plugin.JDBCPersistenceManagerService"
-      name="jboss.messaging:service=PersistenceManager"
-      xmbean-dd="xmdesc/JDBCPersistenceManager-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="UsingBatchUpdates">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, DELIVERY_COUNT INT, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
-   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
-   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
-   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
-   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
-   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
-   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, HEADERS IMAGE, PAYLOAD IMAGE, CHANNEL_COUNT INT, TYPE TINYINT, PRIMARY KEY (MESSAGE_ID))
-   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID BIGINT, BRANCH_QUAL VARBINARY(254), FORMAT_ID INT, GLOBAL_TXID VARBINARY(254), PRIMARY KEY (TRANSACTION_ID))
-   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))
-   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
-   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
-   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
-   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
-   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
-   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
-   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
-   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
-   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
-   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
-   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
-   SELECT_EXISTS_REF=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
-   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
-   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
-   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
-   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
-   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
-   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
-   MESSAGE_ID_COLUMN=MESSAGE_ID
-   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG WITH (HOLDLOCK, ROWLOCK) WHERE MESSAGE_ID = ?
-   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
-   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
-   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
-   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
-   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
-   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
-   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WITH (HOLDLOCK, ROWLOCK) WHERE NAME=?
-   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
-   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
-      ]]></attribute>
-      <attribute name="MaxParams">500</attribute>
-   </mbean>
-
-   <mbean code="org.jboss.messaging.core.plugin.ClusteredPostOfficeService"
-      name="jboss.messaging:service=PostOffice"
-      xmbean-dd="xmdesc/ClusteredPostOffice-xmbean.xml">
-      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
-      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-      <attribute name="PostOfficeName">Clustered JMS</attribute>
-      <attribute name="DataSource">java:/DefaultDS</attribute>
-      <attribute name="CreateTablesOnStartup">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID SMALLINT, QUEUE_NAME VARCHAR(1023), COND VARCHAR(1023), SELECTOR VARCHAR(1023), CHANNEL_ID INTEGER, CLSTERED CHAR(1))
-INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
-DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
-LOAD_BINDINGS=SELECT NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME  = ?
-      ]]></attribute>
-      <attribute name="GroupName">DefaultPostOffice</attribute>
-      <attribute name="StateTimeout">5000</attribute>
-      <attribute name="CastTimeout">5000</attribute>
-      <attribute name="StatsSendPeriod">3000</attribute>
-      <attribute name="MessagePullPolicy">org.jboss.messaging.core.plugin.postoffice.cluster.NullMessagePullPolicy</attribute>
-      <attribute name="ClusterRouterFactory">org.jboss.messaging.core.plugin.postoffice.cluster.DefaultRouterFactory</attribute>
-
-
-      <attribute name="ChannelFactoryName">jgroups.mux:name=Multiplexer</attribute>
-      <attribute name="SyncChannelName">udp-sync</attribute>
-      <attribute name="AsyncChannelName">udp</attribute>
-      <attribute name="ChannelPartitionName">${jboss.partition.name:DefaultPartition}-JMS</attribute>
-
-      <attribute name="AsyncChannelConfig">
-         <config>
-            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
-           mcast_port="45567" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
-           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
-            <AUTOCONF down_thread="false" up_thread="false"/>
-            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
-            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
-            <FD_SOCK down_thread="false" up_thread="false"/>
-            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
-            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
-            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
-                         retransmit_timeout="100,200,600,1200,2400,4800"/>
-            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
-            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
-            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
-            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
-            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
-         </config>
-      </attribute>
-
-      <attribute name="SyncChannelConfig">
-         <config>
-            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
-           mcast_port="45568" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
-           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
-            <AUTOCONF down_thread="false" up_thread="false"/>
-            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
-            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
-            <FD_SOCK down_thread="false" up_thread="false"/>
-            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
-            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
-            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
-                         retransmit_timeout="100,200,600,1200,2400,4800"/>
-            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
-            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
-            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
-            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
-            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
-            <pbcast.STATE_TRANSFER down_thread="false" up_thread="false"/>
-         </config>
-      </attribute>
-   </mbean>
-
-   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
-      name="jboss.messaging:service=JMSUserManager"
-      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
-CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
-SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
-      ]]></attribute>
-   </mbean>
-
-</server>

Deleted: trunk/src/etc/server/default/deploy/clustered-mysql-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/clustered-mysql-persistence-service.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/server/default/deploy/clustered-mysql-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,155 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-     MySql clustered persistence deployment descriptor.
-
-     Tested with MySQL 4.1.22
-
-     $Id$
- -->
-
-<server>
-
-   <mbean code="org.jboss.messaging.core.plugin.JDBCPersistenceManagerService"
-      name="jboss.messaging:service=PersistenceManager"
-      xmbean-dd="xmdesc/JDBCPersistenceManager-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="UsingBatchUpdates">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, DELIVERY_COUNT INTEGER, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
-   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
-   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
-   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
-   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
-   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
-   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, HEADERS MEDIUMBLOB, PAYLOAD LONGBLOB, CHANNEL_COUNT INTEGER, TYPE TINYINT, PRIMARY KEY (MESSAGE_ID))
-   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID BIGINT, BRANCH_QUAL VARBINARY(254), FORMAT_ID INTEGER, GLOBAL_TXID VARBINARY(254), PRIMARY KEY (TRANSACTION_ID))
-   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))
-   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
-   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
-   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
-   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
-   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
-   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
-   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
-   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
-   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD     
-   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
-   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
-   SELECT_EXISTS_REF=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
-   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
-   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
-   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
-   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
-   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
-   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
-   MESSAGE_ID_COLUMN=MESSAGE_ID
-   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ? FOR UPDATE
-   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
-   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
-   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
-   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
-   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
-   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
-   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=? FOR UPDATE
-   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
-   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
-      ]]></attribute>
-      <attribute name="MaxParams">500</attribute>
-   </mbean>
-
-   <mbean code="org.jboss.messaging.core.plugin.ClusteredPostOfficeService"
-      name="jboss.messaging:service=PostOffice"
-      xmbean-dd="xmdesc/ClusteredPostOffice-xmbean.xml">
-      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
-      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-      <attribute name="PostOfficeName">Clustered JMS</attribute>
-      <attribute name="DataSource">java:/DefaultDS</attribute>
-      <attribute name="CreateTablesOnStartup">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID INTEGER, QUEUE_NAME VARCHAR(1023), COND VARCHAR(1023), SELECTOR VARCHAR(1023), CHANNEL_ID BIGINT, CLUSTERED CHAR(1))
-INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
-DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
-LOAD_BINDINGS=SELECT NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME  = ?
-      ]]></attribute>
-      <attribute name="GroupName">DefaultPostOffice</attribute>
-      <attribute name="StateTimeout">5000</attribute>
-      <attribute name="CastTimeout">5000</attribute>
-      <attribute name="StatsSendPeriod">3000</attribute>
-      <attribute name="MessagePullPolicy">org.jboss.messaging.core.plugin.postoffice.cluster.NullMessagePullPolicy</attribute>
-      <attribute name="ClusterRouterFactory">org.jboss.messaging.core.plugin.postoffice.cluster.DefaultRouterFactory</attribute>
-
-
-      <attribute name="ChannelFactoryName">jgroups.mux:name=Multiplexer</attribute>
-      <attribute name="SyncChannelName">udp-sync</attribute>
-      <attribute name="AsyncChannelName">udp</attribute>
-      <attribute name="ChannelPartitionName">${jboss.partition.name:DefaultPartition}-JMS</attribute>
-
-      <attribute name="AsyncChannelConfig">
-         <config>
-            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
-           mcast_port="45567" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
-           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32"/>
-            <AUTOCONF down_thread="false" up_thread="false"/>
-            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
-            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
-            <FD_SOCK down_thread="false" up_thread="false"/>
-            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
-            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
-            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
-                         retransmit_timeout="100,200,600,1200,2400,4800"/>
-            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
-            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
-            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
-            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
-            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
-         </config>
-      </attribute>
-
-      <attribute name="SyncChannelConfig">
-         <config>
-            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
-           mcast_port="45568" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
-           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32"/>
-            <AUTOCONF down_thread="false" up_thread="false"/>
-            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
-            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
-            <FD_SOCK down_thread="false" up_thread="false"/>
-            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
-            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
-            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
-                         retransmit_timeout="100,200,600,1200,2400,4800"/>
-            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
-            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
-            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
-            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
-            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
-            <pbcast.STATE_TRANSFER down_thread="false" up_thread="false"/>
-         </config>
-      </attribute>
-   </mbean>
-
-   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
-      name="jboss.messaging:service=JMSUserManager"
-      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
-CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
-SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
-      ]]></attribute>
-   </mbean>
-
-</server>
\ No newline at end of file

Deleted: trunk/src/etc/server/default/deploy/clustered-oracle-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/clustered-oracle-persistence-service.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/server/default/deploy/clustered-oracle-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,155 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-     Oracle clustered persistence deployment descriptor.
-
-     Tested with Oracle 10.1.0.3
-
-     $Id$
- -->
-
-<server>
-
-   <mbean code="org.jboss.messaging.core.plugin.JDBCPersistenceManagerService"
-      name="jboss.messaging:service=PersistenceManager"
-      xmbean-dd="xmdesc/JDBCPersistenceManager-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="UsingBatchUpdates">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID INTEGER, MESSAGE_ID INTEGER, TRANSACTION_ID INTEGER, STATE CHAR(1), ORD INTEGER, PAGE_ORD INTEGER, DELIVERY_COUNT INTEGER, SCHED_DELIVERY INTEGER, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
-   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
-   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
-   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
-   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
-   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
-   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID INTEGER, RELIABLE CHAR(1), EXPIRATION INTEGER, TIMESTAMP INTEGER, PRIORITY INTEGER, HEADERS BLOB, PAYLOAD BLOB, CHANNEL_COUNT INTEGER, TYPE INTEGER, PRIMARY KEY (MESSAGE_ID))
-   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID INTEGER, BRANCH_QUAL RAW(254), FORMAT_ID INTEGER, GLOBAL_TXID RAW(254), PRIMARY KEY (TRANSACTION_ID))
-   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR2(255), NEXT_ID INTEGER, PRIMARY KEY(NAME))
-   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
-   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
-   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
-   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
-   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
-   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
-   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
-   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
-   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
-   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
-   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
-   SELECT_EXISTS_REF=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
-   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
-   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
-   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
-   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
-   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
-   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
-   MESSAGE_ID_COLUMN=MESSAGE_ID
-   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ? FOR UPDATE
-   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
-   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
-   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
-   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
-   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
-   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
-   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=? FOR UPDATE
-   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
-   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
-      ]]></attribute>
-      <attribute name="MaxParams">500</attribute>
-   </mbean>
-
-   <mbean code="org.jboss.messaging.core.plugin.ClusteredPostOfficeService"
-      name="jboss.messaging:service=PostOffice"
-      xmbean-dd="xmdesc/ClusteredPostOffice-xmbean.xml">
-      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
-      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-      <attribute name="PostOfficeName">Clustered JMS</attribute>
-      <attribute name="DataSource">java:/DefaultDS</attribute>
-      <attribute name="CreateTablesOnStartup">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR2(255), NODE_ID INTEGER, QUEUE_NAME VARCHAR2(1023), COND VARCHAR2(1023), SELECTOR VARCHAR2(1023), CHANNEL_ID INTEGER, CLUSTERED CHAR(1))
-INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
-DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
-LOAD_BINDINGS=SELECT NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME  = ?
-      ]]></attribute>
-      <attribute name="GroupName">DefaultPostOffice</attribute>
-      <attribute name="StateTimeout">5000</attribute>
-      <attribute name="CastTimeout">5000</attribute>
-      <attribute name="StatsSendPeriod">3000</attribute>
-      <attribute name="MessagePullPolicy">org.jboss.messaging.core.plugin.postoffice.cluster.NullMessagePullPolicy</attribute>
-      <attribute name="ClusterRouterFactory">org.jboss.messaging.core.plugin.postoffice.cluster.DefaultRouterFactory</attribute>
-
-
-      <attribute name="ChannelFactoryName">jgroups.mux:name=Multiplexer</attribute>
-      <attribute name="SyncChannelName">udp-sync</attribute>
-      <attribute name="AsyncChannelName">udp</attribute>
-      <attribute name="ChannelPartitionName">${jboss.partition.name:DefaultPartition}-JMS</attribute>
-
-      <attribute name="AsyncChannelConfig">
-         <config>
-            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
-           mcast_port="45567" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
-           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
-            <AUTOCONF down_thread="false" up_thread="false"/>
-            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
-            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
-            <FD_SOCK down_thread="false" up_thread="false"/>
-            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
-            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
-            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
-                         retransmit_timeout="100,200,600,1200,2400,4800"/>
-            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
-            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
-            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
-            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
-            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
-         </config>
-      </attribute>
-
-      <attribute name="SyncChannelConfig">
-         <config>
-            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
-           mcast_port="45568" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
-           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
-            <AUTOCONF down_thread="false" up_thread="false"/>
-            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
-            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
-            <FD_SOCK down_thread="false" up_thread="false"/>
-            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
-            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
-            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
-                         retransmit_timeout="100,200,600,1200,2400,4800"/>
-            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
-            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
-            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
-            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
-            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
-            <pbcast.STATE_TRANSFER down_thread="false" up_thread="false"/>
-         </config>
-      </attribute>
-   </mbean>
-
-   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
-      name="jboss.messaging:service=JMSUserManager"
-      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR2(32) NOT NULL, PASSWD VARCHAR2(32) NOT NULL, CLIENTID VARCHAR2(128), PRIMARY KEY(USER_ID))
-CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR2(32) NOT NULL, USER_ID VARCHAR2(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
-SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
-      ]]></attribute>
-   </mbean>
-
-</server>
\ No newline at end of file

Deleted: trunk/src/etc/server/default/deploy/clustered-postgresql-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/clustered-postgresql-persistence-service.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/server/default/deploy/clustered-postgresql-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,155 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-     Postgresql clustered persistence deployment descriptor.
-
-     Tested with PostgresSQL 8.1.5
-
-     $Id$
- -->
-
-<server>
-
-   <mbean code="org.jboss.messaging.core.plugin.JDBCPersistenceManagerService"
-      name="jboss.messaging:service=PersistenceManager"
-      xmbean-dd="xmdesc/JDBCPersistenceManager-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="UsingBatchUpdates">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, DELIVERY_COUNT INTEGER, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
-   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
-   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
-   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
-   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
-   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
-   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY SMALLINT, HEADERS BYTEA, PAYLOAD BYTEA, CHANNEL_COUNT INTEGER, TYPE SMALLINT, PRIMARY KEY (MESSAGE_ID))
-   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID BIGINT, BRANCH_QUAL BYTEA, FORMAT_ID INTEGER, GLOBAL_TXID BYTEA, PRIMARY KEY (TRANSACTION_ID))
-   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))
-   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
-   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
-   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
-   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
-   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
-   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
-   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
-   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
-   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
-   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
-   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
-   SELECT_EXISTS_REF=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
-   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
-   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
-   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
-   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
-   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
-   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
-   MESSAGE_ID_COLUMN=MESSAGE_ID
-   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ? FOR UPDATE
-   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
-   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
-   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
-   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
-   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
-   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
-   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=? FOR UPDATE
-   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
-   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
-      ]]></attribute>
-      <attribute name="MaxParams">500</attribute>
-   </mbean>
-
-   <mbean code="org.jboss.messaging.core.plugin.ClusteredPostOfficeService"
-      name="jboss.messaging:service=PostOffice"
-      xmbean-dd="xmdesc/ClusteredPostOffice-xmbean.xml">
-      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
-      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-      <attribute name="PostOfficeName">Clustered JMS</attribute>
-      <attribute name="DataSource">java:/DefaultDS</attribute>
-      <attribute name="CreateTablesOnStartup">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID INTEGER, QUEUE_NAME VARCHAR(1023), COND VARCHAR(1023), SELECTOR VARCHAR(1023), CHANNEL_ID BIGINT, CLUSTERED CHAR(1))
-INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
-DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
-LOAD_BINDINGS=SELECT NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME  = ?
-      ]]></attribute>
-      <attribute name="GroupName">DefaultPostOffice</attribute>
-      <attribute name="StateTimeout">5000</attribute>
-      <attribute name="CastTimeout">5000</attribute>
-      <attribute name="StatsSendPeriod">3000</attribute>
-      <attribute name="MessagePullPolicy">org.jboss.messaging.core.plugin.postoffice.cluster.NullMessagePullPolicy</attribute>
-      <attribute name="ClusterRouterFactory">org.jboss.messaging.core.plugin.postoffice.cluster.DefaultRouterFactory</attribute>
-
-
-      <attribute name="ChannelFactoryName">jgroups.mux:name=Multiplexer</attribute>
-      <attribute name="SyncChannelName">udp-sync</attribute>
-      <attribute name="AsyncChannelName">udp</attribute>
-      <attribute name="ChannelPartitionName">${jboss.partition.name:DefaultPartition}-JMS</attribute>
-
-      <attribute name="AsyncChannelConfig">
-         <config>
-            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
-           mcast_port="45567" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
-           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
-            <AUTOCONF down_thread="false" up_thread="false"/>
-            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
-            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
-            <FD_SOCK down_thread="false" up_thread="false"/>
-            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
-            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
-            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
-                         retransmit_timeout="100,200,600,1200,2400,4800"/>
-            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
-            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
-            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
-            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
-            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
-         </config>
-      </attribute>
-
-      <attribute name="SyncChannelConfig">
-         <config>
-            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
-           mcast_port="45568" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
-           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
-            <AUTOCONF down_thread="false" up_thread="false"/>
-            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
-            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
-            <FD_SOCK down_thread="false" up_thread="false"/>
-            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
-            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
-            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
-                         retransmit_timeout="100,200,600,1200,2400,4800"/>
-            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
-            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
-            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
-            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
-            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
-            <pbcast.STATE_TRANSFER down_thread="false" up_thread="false"/>
-         </config>
-      </attribute>
-   </mbean>
-
-   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
-      name="jboss.messaging:service=JMSUserManager"
-      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
-CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
-SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
-      ]]></attribute>
-   </mbean>
-
-</server>
\ No newline at end of file

Deleted: trunk/src/etc/server/default/deploy/clustered-sybase-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/clustered-sybase-persistence-service.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/server/default/deploy/clustered-sybase-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,156 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-     Sybase clustered persistence deployment descriptor.
-
-     Tested with Sybase Adaptive Server Enterprise 12.5.2
-
-     $Id$
- -->
-
-<server>
-
-   <mbean code="org.jboss.messaging.core.plugin.JDBCPersistenceManagerService"
-      name="jboss.messaging:service=PersistenceManager"
-      xmbean-dd="xmdesc/JDBCPersistenceManager-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="UsingBatchUpdates">true</attribute>
-      <attribute name="UsingTrailingByte">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID DECIMAL(19, 0), MESSAGE_ID DECIMAL(19, 0), TRANSACTION_ID DECIMAL(19, 0) NULL, STATE CHAR(1), ORD DECIMAL(19, 0), PAGE_ORD DECIMAL(19, 0) NULL, DELIVERY_COUNT INTEGER, SCHED_DELIVERY DECIMAL(19, 0), PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
-   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
-   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
-   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
-   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
-   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
-   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID DECIMAL(19, 0), RELIABLE CHAR(1), EXPIRATION DECIMAL(19, 0), TIMESTAMP DECIMAL(19, 0), PRIORITY TINYINT, HEADERS IMAGE NULL, PAYLOAD IMAGE NULL, CHANNEL_COUNT INTEGER, TYPE TINYINT, PRIMARY KEY (MESSAGE_ID))
-   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID DECIMAL(19, 0), BRANCH_QUAL VARBINARY(254) NULL, FORMAT_ID INTEGER NULL, GLOBAL_TXID VARBINARY(254) NULL, PRIMARY KEY (TRANSACTION_ID))
-   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID DECIMAL(19, 0), PRIMARY KEY(NAME))
-   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
-   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
-   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
-   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
-   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
-   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
-   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
-   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
-   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
-   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
-   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
-   SELECT_EXISTS_REF=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
-   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
-   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
-   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
-   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
-   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
-   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
-   MESSAGE_ID_COLUMN=MESSAGE_ID
-   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG HOLDLOCK WHERE MESSAGE_ID = ?
-   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
-   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
-   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
-   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
-   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
-   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
-   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER HOLDLOCK WHERE NAME=?
-   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
-   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
-      ]]></attribute>
-      <attribute name="MaxParams">500</attribute>
-   </mbean>
-
-   <mbean code="org.jboss.messaging.core.plugin.ClusteredPostOfficeService"
-      name="jboss.messaging:service=PostOffice"
-      xmbean-dd="xmdesc/ClusteredPostOffice-xmbean.xml">
-      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
-      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-      <attribute name="PostOfficeName">Clustered JMS</attribute>
-      <attribute name="DataSource">java:/DefaultDS</attribute>
-      <attribute name="CreateTablesOnStartup">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID SMALLINT, QUEUE_NAME VARCHAR(1023), COND VARCHAR(1023), SELECTOR VARCHAR(1023) NULL, CHANNEL_ID INTEGER, CLSTERED CHAR(1))
-INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
-DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
-LOAD_BINDINGS=SELECT NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME  = ?
-      ]]></attribute>
-      <attribute name="GroupName">DefaultPostOffice</attribute>
-      <attribute name="StateTimeout">5000</attribute>
-      <attribute name="CastTimeout">5000</attribute>
-      <attribute name="StatsSendPeriod">3000</attribute>
-      <attribute name="MessagePullPolicy">org.jboss.messaging.core.plugin.postoffice.cluster.NullMessagePullPolicy</attribute>
-      <attribute name="ClusterRouterFactory">org.jboss.messaging.core.plugin.postoffice.cluster.DefaultRouterFactory</attribute>
-
-
-      <attribute name="ChannelFactoryName">jgroups.mux:name=Multiplexer</attribute>
-      <attribute name="SyncChannelName">udp-sync</attribute>
-      <attribute name="AsyncChannelName">udp</attribute>
-      <attribute name="ChannelPartitionName">${jboss.partition.name:DefaultPartition}-JMS</attribute>
-
-      <attribute name="AsyncChannelConfig">
-         <config>
-            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
-           mcast_port="45567" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
-           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
-            <AUTOCONF down_thread="false" up_thread="false"/>
-            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
-            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
-            <FD_SOCK down_thread="false" up_thread="false"/>
-            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
-            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
-            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
-                         retransmit_timeout="100,200,600,1200,2400,4800"/>
-            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
-            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
-            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
-            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
-            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
-         </config>
-      </attribute>
-
-      <attribute name="SyncChannelConfig">
-         <config>
-            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
-           mcast_port="45568" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
-           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
-            <AUTOCONF down_thread="false" up_thread="false"/>
-            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
-            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
-            <FD_SOCK down_thread="false" up_thread="false"/>
-            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
-            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
-            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
-                         retransmit_timeout="100,200,600,1200,2400,4800"/>
-            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
-            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
-            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
-            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
-            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
-            <pbcast.STATE_TRANSFER down_thread="false" up_thread="false"/>
-         </config>
-      </attribute>
-   </mbean>
-
-   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
-      name="jboss.messaging:service=JMSUserManager"
-      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
-CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
-SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
-      ]]></attribute>
-   </mbean>
-
-</server>

Modified: trunk/src/etc/server/default/deploy/connection-factories-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/connection-factories-service.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/server/default/deploy/connection-factories-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -31,8 +31,7 @@
 
    <!-- A clustered connection factory that supports automatic failover and load balancing of created
         connections.
-        This factory is not suitable to be used by MDBs,
-        see http://www.jboss.com/index.html?module=bb&op=viewtopic&t=108961
+        This factory is not suitable to be used by MDBs.
    -->
    <mbean code="org.jboss.jms.server.connectionfactory.ConnectionFactory"
       name="jboss.messaging.connectionfactory:service=ClusteredConnectionFactory"
@@ -53,5 +52,90 @@
       <attribute name="SupportsFailover">true</attribute>
       <attribute name="SupportsLoadBalancing">true</attribute>      
    </mbean>
+   
+   <!-- A connection factory with no JNDI bindings that is used in clustering to create the connections that
+        pull messages from one node to another
+   -->
+   <mbean code="org.jboss.jms.server.connectionfactory.ConnectionFactory"
+      name="jboss.messaging.connectionfactory:service=ClusterPullConnectionFactory"
+      xmbean-dd="xmdesc/ConnectionFactory-xmbean.xml">
+      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
+      <depends optional-attribute-name="Connector">jboss.messaging:service=Connector,transport=bisocket</depends>
+      <depends>jboss.messaging:service=PostOffice</depends>
+      <attribute name="SupportsFailover">false</attribute>
+      <attribute name="SupportsLoadBalancing">false</attribute>      
+   </mbean>
+   
+   <!-- An example connection factory with all attributes shown 
+   
+   <mbean code="org.jboss.jms.server.connectionfactory.ConnectionFactory"
+      name="jboss.messaging.connectionfactory:service=MyExampleConnectionFactory"
+      xmbean-dd="xmdesc/ConnectionFactory-xmbean.xml">
+      
+      <constructor>
+      
+         <!- - You can specify the default Client ID to use for connections created using this factory - -> 
+         
+         <arg type="java.lang.String" value="MyClientID"/>
+         
+      </constructor>
+      
+      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
+      
+      <!- - The transport to use - can be bisocket, sslbisocket or http - ->
+      
+      <depends optional-attribute-name="Connector">jboss.messaging:service=Connector,transport=http</depends>
+      
+      <depends>jboss.messaging:service=PostOffice</depends>
+      
+      <!- - PrefetchSize determines the approximate maximum number of messages the client consumer will buffer locally - ->
+      
+      <attribute name="PrefetchSize">150</attribute>
+      
+      <!- - Paging params to be used for temporary queues - ->
+      
+      <attribute name="DefaultTempQueueFullSize">200000</attribute>
+      
+      <attribute name="DefaultTempQueuePageSizeSize">2000</attribute>
+      
+      <attribute name="DefaultTempQueueDownCacheSize">2000</attribute>
+      
+      <!- - The batch size to use when using the DUPS_OK_ACKNOWLEDGE acknowledgement mode - ->
+      
+      <attribute name="DupsOKBatchSize">5000</attribute>
+      
+      <!- - Does this connection factory support automatic failover? - ->
+      
+      <attribute name="SupportsFailover">false</attribute>
+      
+      <!- - Does this connection factory support automatic client side load balancing? - ->
+      
+      <attribute name="SupportsLoadBalancing">false</attribute>  
+            
+      <!- - The class name of the factory used to create the load balancing policy to use on the client side - ->
+      
+      <attribute name="LoadBalancingFactory">org.jboss.jms.client.plugin.RoundRobinLoadBalancingFactory</attribute>  
+      
+      <!- - The connection factory will be bound in the following places in JNDI - ->
 
+      <attribute name="JNDIBindings">
+      
+         <bindings>
+         
+            <binding>/acme/MyExampleConnectionFactory</binding>
+            
+            <binding>/acme/MyExampleConnectionFactoryDupe</binding>
+            
+            <binding>java:/xyz/CF1</binding>
+            
+            <binding>java:/connectionfactories/acme/connection_factory</binding>
+            
+         </bindings>
+         
+      </attribute>   
+       
+   </mbean>
+   
+   -->
+
 </server>
\ No newline at end of file

Deleted: trunk/src/etc/server/default/deploy/db2-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/db2-persistence-service.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/server/default/deploy/db2-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,100 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-     DB2 non-clustered persistence deployment descriptor.
-
-     UNTESTED
-
-     $Id$
- -->
-
-<server>
-
-   <mbean code="org.jboss.messaging.core.plugin.JDBCPersistenceManagerService"
-         name="jboss.messaging:service=PersistenceManager"
-         xmbean-dd="xmdesc/JDBCPersistenceManager-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="UsingBatchUpdates">true</attribute>
-         <attribute name="SqlProperties"><![CDATA[
-   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, DELIVERY_COUNT INTEGER, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
-   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
-   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
-   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
-   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
-   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
-   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY SMALLINT, HEADERS BLOB, PAYLOAD BLOB, CHANNEL_COUNT INTEGER, TYPE SMALLINT, PRIMARY KEY (MESSAGE_ID))
-   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID BIGINT, BRANCH_QUAL BLOB(254), FORMAT_ID INTEGER, GLOBAL_TXID BLOB(254), PRIMARY KEY (TRANSACTION_ID))
-   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))
-   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
-   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
-   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
-   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
-   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
-   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
-   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
-   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
-   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
-   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
-   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
-   SELECT_EXISTS_REF=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
-   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
-   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
-   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
-   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
-   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
-   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
-   MESSAGE_ID_COLUMN=MESSAGE_ID
-   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ? FOR UPDATE
-   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
-   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
-   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
-   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
-   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
-   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
-   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=? FOR UPDATE
-   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
-   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
-         ]]></attribute>
-         <attribute name="MaxParams">500</attribute>
-   </mbean>
-
-   <mbean code="org.jboss.messaging.core.plugin.DefaultPostOfficeService"
-      name="jboss.messaging:service=PostOffice"
-      xmbean-dd="xmdesc/DefaultPostOffice-xmbean.xml">
-      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
-      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-      <attribute name="PostOfficeName">JMS</attribute>
-      <attribute name="DataSource">java:/DefaultDS</attribute>
-      <attribute name="CreateTablesOnStartup">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID INTEGER, QUEUE_NAME VARCHAR(1023), COND VARCHAR(1023), SELECTOR VARCHAR(1023), CHANNEL_ID BIGINT, CLUSTERED CHAR(1))
-INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
-DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
-LOAD_BINDINGS=SELECT NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME  = ?
-      ]]></attribute>
-   </mbean>
-
-   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
-      name="jboss.messaging:service=JMSUserManager"
-      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
-CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
-SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
-      ]]></attribute>
-   </mbean>
-
-</server>
\ No newline at end of file

Copied: trunk/src/etc/server/default/deploy/db2-persistence-service.xml (from rev 2781, trunk/src/etc/server/default/deploy/clustered-db2-persistence-service.xml)
===================================================================
--- trunk/src/etc/server/default/deploy/db2-persistence-service.xml	                        (rev 0)
+++ trunk/src/etc/server/default/deploy/db2-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+     DB2 persistence deployment descriptor.
+
+     UNTESTED
+
+     $Id$
+ -->
+
+<server>
+
+   <!-- Persistence Manager MBean configuration
+       ======================================= -->
+   
+   <mbean code="org.jboss.messaging.core.jmx.JDBCPersistenceManagerService"
+      name="jboss.messaging:service=PersistenceManager"
+      xmbean-dd="xmdesc/JDBCPersistenceManager-xmbean.xml">
+      
+      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
+      
+      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
+      
+      <!-- The datasource to use for the persistence manager -->
+      <attribute name="DataSource">java:/DefaultDS</attribute>
+      
+      <!-- If true will attempt to create tables and indexes on every start-up -->
+      <attribute name="CreateTablesOnStartup">true</attribute>
+      
+      <!-- If true then will use JDBC batch updates -->
+      <attribute name="UsingBatchUpdates">true</attribute>
+      
+      <attribute name="SqlProperties"><![CDATA[
+   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, DELIVERY_COUNT INTEGER, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
+   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
+   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
+   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
+   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
+   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
+   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY SMALLINT, HEADERS BLOB, PAYLOAD BLOB, CHANNEL_COUNT INTEGER, TYPE SMALLINT, PRIMARY KEY (MESSAGE_ID))
+   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID BIGINT, BRANCH_QUAL BLOB(254), FORMAT_ID INTEGER, GLOBAL_TXID BLOB(254), PRIMARY KEY (TRANSACTION_ID))
+   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))
+   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
+   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
+   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
+   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
+   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
+   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
+   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
+   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
+   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
+   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
+   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
+   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
+   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
+   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
+   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
+   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
+   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
+   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
+   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
+   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
+   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
+   MESSAGE_ID_COLUMN=MESSAGE_ID
+   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ? FOR UPDATE
+   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
+   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
+   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
+   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
+   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
+   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
+   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=? FOR UPDATE
+   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
+   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
+      ]]></attribute>
+      
+      <!-- The maximum number of parameters to include in a prepared statement -->
+      
+      <attribute name="MaxParams">500</attribute>
+   </mbean>
+
+   <!-- Messaging Post Office MBean configuration
+        ========================================= -->
+   
+   <mbean code="org.jboss.messaging.core.jmx.MessagingPostOfficeService"
+      name="jboss.messaging:service=PostOffice"
+      xmbean-dd="xmdesc/MessagingPostOffice-xmbean.xml">
+      
+      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
+      
+      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
+            
+      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
+      
+      <!-- The name of the post office -->
+      
+      <attribute name="PostOfficeName">JMS post office</attribute>
+      
+      <!-- The datasource used by the post office to access it's binding information -->      
+      
+      <attribute name="DataSource">java:/DefaultDS</attribute>
+      
+      <!-- If true will attempt to create tables and indexes on every start-up -->
+      
+      <attribute name="CreateTablesOnStartup">true</attribute>
+      
+      <attribute name="SqlProperties"><![CDATA[
+CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID INTEGER, QUEUE_NAME VARCHAR(1023), COND VARCHAR(1023), SELECTOR VARCHAR(1023), CHANNEL_ID BIGINT, CLUSTERED CHAR(1))
+INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
+DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
+LOAD_BINDINGS=SELECT QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=?
+      ]]></attribute>
+      
+      <!-- This post office is clustered. If you don't want a clustered post office then set to false -->
+      
+      <attribute name="Clustered">true</attribute>
+      
+      <!-- All the remaining properties only have to be specified if the post office is clustered.
+           You can safely comment them out if your post office is non clustered -->
+      
+      <!-- The JGroups group name that the post office will use -->
+      
+      <attribute name="GroupName">MessagingPostOffice</attribute>
+      
+      <!-- Max time to wait for state to arrive when the post office joins the cluster -->
+      
+      <attribute name="StateTimeout">5000</attribute>
+      
+      <!-- Max time to wait for a synchronous call to node members using the MessageDispatcher -->
+      
+      <attribute name="CastTimeout">5000</attribute>
+      
+      <!-- Enable this when the JGroups multiplexer comes of age 
+      <attribute name="ChannelFactoryName">jgroups.mux:name=Multiplexer</attribute>
+      <attribute name="SyncChannelName">udp-sync</attribute>
+      <attribute name="AsyncChannelName">udp</attribute>
+      <attribute name="ChannelPartitionName">${jboss.partition.name:DefaultPartition}-JMS</attribute>     
+      -->
+      
+      <!-- JGroups stack configuration for the data channel - used when casting messages across the cluster -->
+      
+      <attribute name="AsyncChannelConfig">
+         <config>
+            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
+           mcast_port="45567" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
+           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
+            <AUTOCONF down_thread="false" up_thread="false"/>
+            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
+            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
+            <FD_SOCK down_thread="false" up_thread="false"/>
+            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
+            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
+            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
+                         retransmit_timeout="100,200,600,1200,2400,4800"/>
+            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
+            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
+            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
+            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
+            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
+         </config>
+      </attribute>
+      
+      <!-- JGroups stack configuration to use for the control channel - used for bind/unbind requests amongst others -->
+      
+      <attribute name="SyncChannelConfig">
+         <config>
+            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
+           mcast_port="45568" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
+           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
+            <AUTOCONF down_thread="false" up_thread="false"/>
+            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
+            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
+            <FD_SOCK down_thread="false" up_thread="false"/>
+            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
+            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
+            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
+                         retransmit_timeout="100,200,600,1200,2400,4800"/>
+            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
+            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
+            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
+            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
+            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
+            <pbcast.STATE_TRANSFER down_thread="false" up_thread="false"/>
+         </config>
+      </attribute>
+   </mbean>
+
+   <!-- Messaging JMS User Manager MBean config
+        ======================================= -->
+
+   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
+      name="jboss.messaging:service=JMSUserManager"
+      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
+CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
+SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
+POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
+      ]]></attribute>
+   </mbean>
+
+</server>
\ No newline at end of file

Modified: trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -2,43 +2,87 @@
 
 <!--
      Hypersonic persistence deployment descriptor.
+     
+     DO NOT USE HYPERSONIC IN PRODUCTION or in a clustered environment- Hypersonic does not have transaction isolation
 
      $Id$
  -->
 
 <server>
 
-   <mbean code="org.jboss.messaging.core.plugin.JDBCPersistenceManagerService"
+   <!-- Persistence Manager MBean configuration
+       ======================================= -->
+   
+   <mbean code="org.jboss.messaging.core.jmx.JDBCPersistenceManagerService"
       name="jboss.messaging:service=PersistenceManager"
       xmbean-dd="xmdesc/JDBCPersistenceManager-xmbean.xml">
+      
       <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
+      
       <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
+            
+      <!-- The datasource to use for the persistence manager -->
+                                
       <attribute name="DataSource">java:/DefaultDS</attribute>
+      
+      <!-- If true will attempt to create tables and indexes on every start-up -->
+                  
       <attribute name="CreateTablesOnStartup">true</attribute>
+      
+      <!-- If true then will use JDBC batch updates -->
+                 
       <attribute name="UsingBatchUpdates">false</attribute>
+      
+      <!-- The maximum number of parameters to include in a prepared statement -->            
+      
       <attribute name="MaxParams">500</attribute>
    </mbean>
 
-   <!-- Note that Hypersonic CANNOT be used for clustered post offices -->
-
-   <mbean code="org.jboss.messaging.core.plugin.DefaultPostOfficeService"
-      name="jboss.messaging:service=PostOffice"
-      xmbean-dd="xmdesc/DefaultPostOffice-xmbean.xml">
+   <!-- Messaging Post Office MBean configuration
+        ========================================= -->
+   
+   <mbean code="org.jboss.messaging.core.jmx.MessagingPostOfficeService"
+      name="jboss.messaging:service=PostOffice"      
+      xmbean-dd="xmdesc/MessagingPostOffice-xmbean.xml">
+            
       <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
+      
       <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
+      
       <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-      <attribute name="PostOfficeName">JMS</attribute>
+      
+      <!-- The name of the post office -->      
+                 
+      <attribute name="PostOfficeName">JMS post office</attribute>
+      
+      <!-- The datasource used by the post office to access it's binding information -->                       
+      
       <attribute name="DataSource">java:/DefaultDS</attribute>
+      
+      <!-- If true will attempt to create tables and indexes on every start-up -->
+                        
       <attribute name="CreateTablesOnStartup">true</attribute>
+      
+      <!-- This post office is NON CLUSTERED - do not use clustering with Hypersonic!! -->
+      
+      <attribute name="Clustered">false</attribute>
    </mbean>
 
+   <!-- Messaging JMS User Manager MBean config
+        ======================================= -->
+   
    <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
       name="jboss.messaging:service=JMSUserManager"
       xmbean-dd="xmdesc/JMSUserManager-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[
 POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
       ]]></attribute>

Modified: trunk/src/etc/server/default/deploy/messaging-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/messaging-service.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/server/default/deploy/messaging-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -8,34 +8,94 @@
 
 <server>
 
+   <!-- ServerPeer MBean configuration
+        ============================== -->
+
    <mbean code="org.jboss.jms.server.ServerPeer"
       name="jboss.messaging:service=ServerPeer"
       xmbean-dd="xmdesc/ServerPeer-xmbean.xml">
 
+      <!-- The unique id of the server peer - in a cluster each node MUST have a unique value - must be an integer -->
+
       <attribute name="ServerPeerID">0</attribute>
+      
+      <!-- The default JNDI context to use for queues when they are deployed without specifying one --> 
+      
       <attribute name="DefaultQueueJNDIContext">/queue</attribute>
+      
+      <!-- The default JNDI context to use for topics when they are deployed without specifying one --> 
+      
       <attribute name="DefaultTopicJNDIContext">/topic</attribute>
 
 	  <attribute name="PostOffice">jboss.messaging:service=PostOffice</attribute>
+	  
+	  <!-- The JAAS security domain to use for JBoss Messaging -->
+	  
       <attribute name="SecurityDomain">java:/jaas/messaging</attribute>
+      
+      <!-- The default security configuration to apply to destinations - this can be overridden on a per destination basis -->
+      
       <attribute name="DefaultSecurityConfig">
         <security>
             <role name="guest" read="true" write="true" create="true"/>
         </security>
       </attribute>
+      
+      <!-- The default Dead Letter Queue (DLQ) to use for destinations.
+           This can be overridden on a per destinatin basis -->
+      
       <attribute name="DefaultDLQ">jboss.messaging.destination:service=Queue,name=DLQ</attribute>
+      
+      <!-- The default maximum number of times to attempt delivery of a message before sending to the DLQ (if configured).
+           This can be overridden on a per destinatin basis -->
+      
       <attribute name="DefaultMaxDeliveryAttempts">10</attribute>
+      
+      <!-- The default Expiry Queue to use for destinations. This can be overridden on a per destinatin basis -->
+      
       <attribute name="DefaultExpiryQueue">jboss.messaging.destination:service=Queue,name=ExpiryQueue</attribute>
+      
+      <!-- The default redelivery delay to impose. This can be overridden on a per destination basis -->
+      
       <attribute name="DefaultRedeliveryDelay">0</attribute>
-      <attribute name="QueueStatsSamplePeriod">5000</attribute>
+      
+      <!-- The periodicity of the message counter manager enquiring on queues for statistics -->
+      
+      <attribute name="MessageCounterSamplePeriod">5000</attribute>
+      
+      <!-- The maximum amount of time for a client to wait for failover to start on the server side after
+           it has detected failure -->
+      
       <attribute name="FailoverStartTimeout">60000</attribute>
+      
+      <!-- The maximum amount of time for a client to wait for failover to complete on the server side after
+           it has detected failure -->
+      
       <attribute name="FailoverCompleteTimeout">300000</attribute>
+      
+      <!-- The maximum number of days results to maintain in the message counter history -->
+      
       <attribute name="DefaultMessageCounterHistoryDayLimit">-1</attribute>
+      
+      <!-- The name of the connection factory to use for creating connections between nodes to pull messages -->
+      
+      <attribute name="ClusterPullConnectionFactoryName">jboss.messaging.connectionfactory:service=ClusterPullConnectionFactory</attribute>
+      
+      <!-- Use XA when pulling persistent messages from a remote node to this one. -->
+      
+      <attribute name="UseXAForMessagePull">true</attribute>
+      
+      <!-- When redistributing messages in the cluster. Do we need to preserve the order of messages received
+            by a particular consumer from a particular producer? -->
+            
+      <attribute name="DefaultPreserveOrdering">false</attribute>
 
       <depends optional-attribute-name="PersistenceManager">jboss.messaging:service=PersistenceManager</depends>
+      
       <depends optional-attribute-name="JMSUserManager">jboss.messaging:service=JMSUserManager</depends>
+      
       <depends>jboss.messaging:service=Connector,transport=bisocket</depends>
 
    </mbean>
 
-</server>
\ No newline at end of file
+</server>

Deleted: trunk/src/etc/server/default/deploy/mssql-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/mssql-persistence-service.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/server/default/deploy/mssql-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,100 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-     MS SQL Server non-clustered persistence deployment descriptor.
-
-     Tested with SQL Server 2005
-
-     $Id$
- -->
-
-<server>
-
-   <mbean code="org.jboss.messaging.core.plugin.JDBCPersistenceManagerService"
-         name="jboss.messaging:service=PersistenceManager"
-         xmbean-dd="xmdesc/JDBCPersistenceManager-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="UsingBatchUpdates">true</attribute>
-         <attribute name="SqlProperties"><![CDATA[
-   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, DELIVERY_COUNT INT, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
-   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
-   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
-   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
-   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
-   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
-   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, HEADERS IMAGE, PAYLOAD IMAGE, CHANNEL_COUNT INT, TYPE TINYINT, PRIMARY KEY (MESSAGE_ID))
-   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID BIGINT, BRANCH_QUAL VARBINARY(254), FORMAT_ID INT, GLOBAL_TXID VARBINARY(254), PRIMARY KEY (TRANSACTION_ID))
-   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))
-   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
-   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
-   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
-   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
-   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
-   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
-   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
-   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
-   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
-   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
-   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
-   SELECT_EXISTS_REF=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
-   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
-   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
-   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
-   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
-   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
-   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
-   MESSAGE_ID_COLUMN=MESSAGE_ID
-   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG WITH (HOLDLOCK, ROWLOCK) WHERE MESSAGE_ID = ?
-   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
-   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
-   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
-   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
-   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
-   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
-   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WITH (HOLDLOCK, ROWLOCK) WHERE NAME=?
-   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
-   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
-         ]]></attribute>
-         <attribute name="MaxParams">500</attribute>
-   </mbean>
-
-   <mbean code="org.jboss.messaging.core.plugin.DefaultPostOfficeService"
-      name="jboss.messaging:service=PostOffice"
-      xmbean-dd="xmdesc/DefaultPostOffice-xmbean.xml">
-      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
-      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-      <attribute name="PostOfficeName">JMS</attribute>
-      <attribute name="DataSource">java:/DefaultDS</attribute>
-      <attribute name="CreateTablesOnStartup">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID SMALLINT, QUEUE_NAME VARCHAR(1023), COND VARCHAR(1023), SELECTOR VARCHAR(1023), CHANNEL_ID INTEGER, CLSTERED CHAR(1))
-INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
-DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
-LOAD_BINDINGS=SELECT NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME  = ?
-      ]]></attribute>
-   </mbean>
-
-   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
-      name="jboss.messaging:service=JMSUserManager"
-      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
-CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
-SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
-      ]]></attribute>
-   </mbean>
-
-</server>

Copied: trunk/src/etc/server/default/deploy/mssql-persistence-service.xml (from rev 2781, trunk/src/etc/server/default/deploy/clustered-mssql-persistence-service.xml)
===================================================================
--- trunk/src/etc/server/default/deploy/mssql-persistence-service.xml	                        (rev 0)
+++ trunk/src/etc/server/default/deploy/mssql-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+     MS SQL Server persistence deployment descriptor.
+
+     Tested with SQL Server 2005
+
+     $Id$
+ -->
+
+<server>
+
+   <!-- Persistence Manager MBean configuration
+       ======================================= -->
+   
+   <mbean code="org.jboss.messaging.core.jmx.JDBCPersistenceManagerService"
+      name="jboss.messaging:service=PersistenceManager"
+      xmbean-dd="xmdesc/JDBCPersistenceManager-xmbean.xml">
+      
+      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
+      
+      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
+      
+      <!-- The datasource to use for the persistence manager -->
+        
+      <attribute name="DataSource">java:/DefaultDS</attribute>
+      
+      <!-- If true will attempt to create tables and indexes on every start-up -->
+      
+      <attribute name="CreateTablesOnStartup">true</attribute>
+      
+      <!-- If true then will use JDBC batch updates -->
+      
+      <attribute name="UsingBatchUpdates">true</attribute>
+      
+      <attribute name="SqlProperties"><![CDATA[
+   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, DELIVERY_COUNT INT, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
+   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
+   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
+   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
+   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
+   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
+   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, HEADERS IMAGE, PAYLOAD IMAGE, CHANNEL_COUNT INT, TYPE TINYINT, PRIMARY KEY (MESSAGE_ID))
+   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID BIGINT, BRANCH_QUAL VARBINARY(254), FORMAT_ID INT, GLOBAL_TXID VARBINARY(254), PRIMARY KEY (TRANSACTION_ID))
+   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))
+   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
+   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
+   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
+   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
+   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
+   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
+   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
+   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
+   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
+   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
+   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
+   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
+   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
+   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
+   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
+   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
+   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
+   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
+   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
+   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
+   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
+   MESSAGE_ID_COLUMN=MESSAGE_ID
+   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG WITH (HOLDLOCK, ROWLOCK) WHERE MESSAGE_ID = ?
+   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
+   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
+   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
+   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
+   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
+   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
+   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WITH (HOLDLOCK, ROWLOCK) WHERE NAME=?
+   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
+   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
+      ]]></attribute>
+      
+      <!-- The maximum number of parameters to include in a prepared statement -->
+      
+      <attribute name="MaxParams">500</attribute>
+   </mbean>
+
+   <!-- Messaging Post Office MBean configuration
+        ========================================= -->
+   
+   <mbean code="org.jboss.messaging.core.jmx.MessagingPostOfficeService"
+      name="jboss.messaging:service=PostOffice"
+      xmbean-dd="xmdesc/MessagingPostOffice-xmbean.xml">
+      
+      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
+                 
+      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
+      
+      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
+      
+      <!-- The name of the post office -->      
+      
+      <attribute name="PostOfficeName">JMS post office</attribute>
+      
+      <!-- The datasource used by the post office to access it's binding information -->      
+            
+      <attribute name="DataSource">java:/DefaultDS</attribute>
+      
+      <!-- If true will attempt to create tables and indexes on every start-up -->
+            
+      <attribute name="CreateTablesOnStartup">true</attribute>
+      
+      <attribute name="SqlProperties"><![CDATA[
+CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID SMALLINT, QUEUE_NAME VARCHAR(1023), COND VARCHAR(1023), SELECTOR VARCHAR(1023), CHANNEL_ID INTEGER, CLSTERED CHAR(1))
+INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
+DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
+LOAD_BINDINGS=SELECT QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=?
+      ]]></attribute>
+      
+      <!-- This post office is clustered. If you don't want a clustered post office then set to false -->
+      
+      <attribute name="Clustered">true</attribute>
+      
+      <!-- All the remaining properties only have to be specified if the post office is clustered.
+           You can safely comment them out if your post office is non clustered -->
+      
+      <!-- The JGroups group name that the post office will use -->      
+            
+      <attribute name="GroupName">MessagingPostOffice</attribute>
+      
+      <!-- Max time to wait for state to arrive when the post office joins the cluster -->            
+      
+      <attribute name="StateTimeout">5000</attribute>
+      
+      <!-- Max time to wait for a synchronous call to node members using the MessageDispatcher -->            
+      
+      <attribute name="CastTimeout">5000</attribute>
+      
+      <!-- Enable this when the JGroups multiplexer comes of age
+      <attribute name="ChannelFactoryName">jgroups.mux:name=Multiplexer</attribute>      
+      <attribute name="SyncChannelName">udp-sync</attribute>
+      <attribute name="AsyncChannelName">udp</attribute>
+      <attribute name="ChannelPartitionName">${jboss.partition.name:DefaultPartition}-JMS</attribute>
+      -->
+      
+      <!-- JGroups stack configuration for the data channel - used when casting messages across the cluster -->
+                  
+      <attribute name="AsyncChannelConfig">
+         <config>
+            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
+           mcast_port="45567" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
+           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
+            <AUTOCONF down_thread="false" up_thread="false"/>
+            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
+            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
+            <FD_SOCK down_thread="false" up_thread="false"/>
+            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
+            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
+            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
+                         retransmit_timeout="100,200,600,1200,2400,4800"/>
+            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
+            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
+            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
+            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
+            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
+         </config>
+      </attribute>
+      
+      <!-- JGroups stack configuration to use for the control channel - used for bind/unbind requests amongst others -->           
+      
+      <attribute name="SyncChannelConfig">
+         <config>
+            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
+           mcast_port="45568" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
+           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
+            <AUTOCONF down_thread="false" up_thread="false"/>
+            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
+            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
+            <FD_SOCK down_thread="false" up_thread="false"/>
+            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
+            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
+            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
+                         retransmit_timeout="100,200,600,1200,2400,4800"/>
+            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
+            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
+            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
+            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
+            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
+            <pbcast.STATE_TRANSFER down_thread="false" up_thread="false"/>
+         </config>
+      </attribute>
+   </mbean>
+   
+   <!-- Messaging JMS User Manager MBean config
+        ======================================= -->
+   
+   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
+      name="jboss.messaging:service=JMSUserManager"
+      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
+CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
+SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
+POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
+      ]]></attribute>
+   </mbean>
+
+</server>

Deleted: trunk/src/etc/server/default/deploy/mysql-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/mysql-persistence-service.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/server/default/deploy/mysql-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,100 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-     MySql persistence deployment descriptor.
-
-     Tested with MySQL 4.1.22
-
-     $Id$
- -->
-
-<server>
-
-   <mbean code="org.jboss.messaging.core.plugin.JDBCPersistenceManagerService"
-         name="jboss.messaging:service=PersistenceManager"
-         xmbean-dd="xmdesc/JDBCPersistenceManager-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="UsingBatchUpdates">true</attribute>
-         <attribute name="SqlProperties"><![CDATA[
-   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, DELIVERY_COUNT INTEGER, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
-   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
-   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
-   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
-   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
-   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
-   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, HEADERS MEDIUMBLOB, PAYLOAD LONGBLOB, CHANNEL_COUNT INTEGER, TYPE TINYINT, PRIMARY KEY (MESSAGE_ID))
-   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID BIGINT, BRANCH_QUAL VARBINARY(254), FORMAT_ID INTEGER, GLOBAL_TXID VARBINARY(254), PRIMARY KEY (TRANSACTION_ID))
-   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))
-   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
-   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
-   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
-   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
-   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
-   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
-   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
-   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
-   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
-   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
-   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
-   SELECT_EXISTS_REF=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
-   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
-   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
-   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
-   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
-   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
-   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
-   MESSAGE_ID_COLUMN=MESSAGE_ID
-   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ? FOR UPDATE
-   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
-   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
-   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
-   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
-   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
-   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
-   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=? FOR UPDATE
-   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
-   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
-         ]]></attribute>
-         <attribute name="MaxParams">500</attribute>
-   </mbean>
-
-   <mbean code="org.jboss.messaging.core.plugin.DefaultPostOfficeService"
-      name="jboss.messaging:service=PostOffice"
-      xmbean-dd="xmdesc/DefaultPostOffice-xmbean.xml">
-      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
-      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-      <attribute name="PostOfficeName">JMS</attribute>
-      <attribute name="DataSource">java:/DefaultDS</attribute>
-      <attribute name="CreateTablesOnStartup">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID INTEGER, QUEUE_NAME VARCHAR(1023), COND VARCHAR(1023), SELECTOR VARCHAR(1023), CHANNEL_ID BIGINT, CLUSTERED CHAR(1))
-INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
-DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
-LOAD_BINDINGS=SELECT NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME  = ?
-      ]]></attribute>
-   </mbean>
-
-   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
-      name="jboss.messaging:service=JMSUserManager"
-      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
-CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
-SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
-      ]]></attribute>
-   </mbean>
-
-</server>
\ No newline at end of file

Copied: trunk/src/etc/server/default/deploy/mysql-persistence-service.xml (from rev 2781, trunk/src/etc/server/default/deploy/clustered-mysql-persistence-service.xml)
===================================================================
--- trunk/src/etc/server/default/deploy/mysql-persistence-service.xml	                        (rev 0)
+++ trunk/src/etc/server/default/deploy/mysql-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+     MySql persistence deployment descriptor.
+
+     Tested with MySQL 4.1.22
+
+     $Id$
+ -->
+
+<server>
+
+   <!-- Persistence Manager MBean configuration
+       ======================================= -->
+   
+   <mbean code="org.jboss.messaging.core.jmx.JDBCPersistenceManagerService"
+      name="jboss.messaging:service=PersistenceManager"
+      xmbean-dd="xmdesc/JDBCPersistenceManager-xmbean.xml">
+      
+      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
+      
+      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
+      
+      <!-- The datasource to use for the persistence manager -->
+                    
+      <attribute name="DataSource">java:/DefaultDS</attribute>      
+      
+      <!-- If true will attempt to create tables and indexes on every start-up -->
+                  
+      <attribute name="CreateTablesOnStartup">true</attribute>
+      
+      <!-- If true then will use JDBC batch updates -->
+                  
+      <attribute name="UsingBatchUpdates">true</attribute>
+      
+      <attribute name="SqlProperties"><![CDATA[
+   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, DELIVERY_COUNT INTEGER, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
+   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
+   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
+   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
+   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
+   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
+   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, HEADERS MEDIUMBLOB, PAYLOAD LONGBLOB, CHANNEL_COUNT INTEGER, TYPE TINYINT, PRIMARY KEY (MESSAGE_ID))
+   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID BIGINT, BRANCH_QUAL VARBINARY(254), FORMAT_ID INTEGER, GLOBAL_TXID VARBINARY(254), PRIMARY KEY (TRANSACTION_ID))
+   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))
+   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
+   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
+   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
+   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
+   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
+   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
+   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
+   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
+   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
+   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
+   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD     
+   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
+   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
+   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
+   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
+   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
+   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
+   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
+   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
+   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
+   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
+   MESSAGE_ID_COLUMN=MESSAGE_ID
+   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ? FOR UPDATE
+   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
+   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
+   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
+   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
+   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
+   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
+   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=? FOR UPDATE
+   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
+   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
+      ]]></attribute>
+      
+      <!-- The maximum number of parameters to include in a prepared statement -->
+                  
+      <attribute name="MaxParams">500</attribute>
+   </mbean>
+
+   <!-- Messaging Post Office MBean configuration
+        ========================================= -->
+   
+   <mbean code="org.jboss.messaging.core.jmx.MessagingPostOfficeService"
+      name="jboss.messaging:service=PostOffice"
+      xmbean-dd="xmdesc/MessagingPostOffice-xmbean.xml">
+      
+      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
+                
+      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
+      
+      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
+      
+      <!-- The name of the post office -->                  
+      
+      <attribute name="PostOfficeName">JMS post office</attribute>
+      
+      <!-- The datasource used by the post office to access it's binding information -->                     
+      
+      <attribute name="DataSource">java:/DefaultDS</attribute>
+      
+      <!-- If true will attempt to create tables and indexes on every start-up -->
+                        
+      <attribute name="CreateTablesOnStartup">true</attribute>
+      
+      <attribute name="SqlProperties"><![CDATA[
+CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID INTEGER, QUEUE_NAME VARCHAR(1023), COND VARCHAR(1023), SELECTOR VARCHAR(1023), CHANNEL_ID BIGINT, CLUSTERED CHAR(1))
+INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
+DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
+LOAD_BINDINGS=SELECT QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=?
+      ]]></attribute>
+       
+      <!-- This post office is clustered. If you don't want a clustered post office then set to false -->
+      
+      <attribute name="Clustered">true</attribute>
+      
+      <!-- All the remaining properties only have to be specified if the post office is clustered.
+           You can safely comment them out if your post office is non clustered -->
+      
+      <!-- The JGroups group name that the post office will use -->            
+      
+      <attribute name="GroupName">MessagingPostOffice</attribute>
+      
+      <!-- Max time to wait for state to arrive when the post office joins the cluster -->            
+                  
+      <attribute name="StateTimeout">5000</attribute>
+      
+      <!-- Max time to wait for a synchronous call to node members using the MessageDispatcher -->            
+                  
+      <attribute name="CastTimeout">5000</attribute>
+      
+      <!-- Enable this when the JGroups multiplexer comes of age
+      <attribute name="ChannelFactoryName">jgroups.mux:name=Multiplexer</attribute>      
+      <attribute name="SyncChannelName">udp-sync</attribute>
+      <attribute name="AsyncChannelName">udp</attribute>
+      <attribute name="ChannelPartitionName">${jboss.partition.name:DefaultPartition}-JMS</attribute>
+      -->
+      
+      <!-- JGroups stack configuration for the data channel - used when casting messages across the cluster -->               
+      
+      <attribute name="AsyncChannelConfig">
+         <config>
+            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
+           mcast_port="45567" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
+           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32"/>
+            <AUTOCONF down_thread="false" up_thread="false"/>
+            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
+            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
+            <FD_SOCK down_thread="false" up_thread="false"/>
+            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
+            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
+            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
+                         retransmit_timeout="100,200,600,1200,2400,4800"/>
+            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
+            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
+            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
+            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
+            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
+         </config>
+      </attribute>
+      
+      <!-- JGroups stack configuration to use for the control channel - used for bind/unbind requests amongst others -->           
+                  
+      <attribute name="SyncChannelConfig">
+         <config>
+            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
+           mcast_port="45568" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
+           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32"/>
+            <AUTOCONF down_thread="false" up_thread="false"/>
+            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
+            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
+            <FD_SOCK down_thread="false" up_thread="false"/>
+            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
+            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
+            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
+                         retransmit_timeout="100,200,600,1200,2400,4800"/>
+            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
+            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
+            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
+            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
+            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
+            <pbcast.STATE_TRANSFER down_thread="false" up_thread="false"/>
+         </config>
+      </attribute>
+   </mbean>
+   
+   <!-- Messaging JMS User Manager MBean config
+        ======================================= -->
+      
+   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
+      name="jboss.messaging:service=JMSUserManager"
+      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
+CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
+SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
+POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
+      ]]></attribute>
+   </mbean>
+
+</server>

Deleted: trunk/src/etc/server/default/deploy/oracle-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/oracle-persistence-service.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/server/default/deploy/oracle-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,101 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-     Oracle non-clustered persistence deployment descriptor.
-
-     Tested with Oracle 10.1.0.3
-
-     $Id$
- -->
-
-<server>
-
-   <mbean code="org.jboss.messaging.core.plugin.JDBCPersistenceManagerService"
-      name="jboss.messaging:service=PersistenceManager"
-      xmbean-dd="xmdesc/JDBCPersistenceManager-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="UsingBatchUpdates">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID INTEGER, MESSAGE_ID INTEGER, TRANSACTION_ID INTEGER, STATE CHAR(1), ORD INTEGER, PAGE_ORD INTEGER, DELIVERY_COUNT INTEGER, SCHED_DELIVERY INTEGER, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
-   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
-   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
-   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
-   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
-   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
-   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID INTEGER, RELIABLE CHAR(1), EXPIRATION INTEGER, TIMESTAMP INTEGER, PRIORITY INTEGER, HEADERS BLOB, PAYLOAD BLOB, CHANNEL_COUNT INTEGER, TYPE INTEGER, PRIMARY KEY (MESSAGE_ID))
-   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID INTEGER, BRANCH_QUAL RAW(254), FORMAT_ID INTEGER, GLOBAL_TXID RAW(254), PRIMARY KEY (TRANSACTION_ID))
-   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR2(255), NEXT_ID INTEGER, PRIMARY KEY(NAME))
-   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
-   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
-   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
-   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
-   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
-   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
-   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
-   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
-   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
-   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
-   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
-   SELECT_EXISTS_REF=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
-   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
-   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
-   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
-   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
-   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
-   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
-   MESSAGE_ID_COLUMN=MESSAGE_ID
-   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ? FOR UPDATE
-   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
-   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
-   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
-   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
-   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
-   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
-   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=? FOR UPDATE
-   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
-   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
-      ]]></attribute>
-      <attribute name="MaxParams">500</attribute>
-   </mbean>
-
-
-   <mbean code="org.jboss.messaging.core.plugin.DefaultPostOfficeService"
-      name="jboss.messaging:service=PostOffice"
-      xmbean-dd="xmdesc/DefaultPostOffice-xmbean.xml">
-      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
-      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-      <attribute name="PostOfficeName">JMS</attribute>
-      <attribute name="DataSource">java:/DefaultDS</attribute>
-      <attribute name="CreateTablesOnStartup">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR2(255), NODE_ID INTEGER, QUEUE_NAME VARCHAR2(1023), COND VARCHAR2(1023), SELECTOR VARCHAR2(1023), CHANNEL_ID INTEGER, CLUSTERED CHAR(1))
-INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
-DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
-LOAD_BINDINGS=SELECT NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME  = ?
-      ]]></attribute>
-   </mbean>
-
-   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
-      name="jboss.messaging:service=JMSUserManager"
-      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR2(32) NOT NULL, PASSWD VARCHAR2(32) NOT NULL, CLIENTID VARCHAR2(128), PRIMARY KEY(USER_ID))
-CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR2(32) NOT NULL, USER_ID VARCHAR2(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
-SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
-      ]]></attribute>
-   </mbean>
-
-</server>
\ No newline at end of file

Copied: trunk/src/etc/server/default/deploy/oracle-persistence-service.xml (from rev 2781, trunk/src/etc/server/default/deploy/clustered-oracle-persistence-service.xml)
===================================================================
--- trunk/src/etc/server/default/deploy/oracle-persistence-service.xml	                        (rev 0)
+++ trunk/src/etc/server/default/deploy/oracle-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+     Oracle persistence deployment descriptor.
+
+     Tested with Oracle 10.1.0.3
+
+     $Id$
+ -->
+
+<server>
+
+   <!-- Persistence Manager MBean configuration
+       ======================================= -->
+   
+   <mbean code="org.jboss.messaging.core.jmx.JDBCPersistenceManagerService"
+      name="jboss.messaging:service=PersistenceManager"
+      xmbean-dd="xmdesc/JDBCPersistenceManager-xmbean.xml">
+      
+      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
+      
+      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
+      
+      <!-- The datasource to use for the persistence manager -->
+                    
+      <attribute name="DataSource">java:/DefaultDS</attribute>
+      
+      <!-- If true will attempt to create tables and indexes on every start-up -->
+                  
+      <attribute name="CreateTablesOnStartup">true</attribute>
+      
+      <!-- If true then will use JDBC batch updates -->
+                  
+      <attribute name="UsingBatchUpdates">true</attribute>
+      
+      <attribute name="SqlProperties"><![CDATA[
+   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID INTEGER, MESSAGE_ID INTEGER, TRANSACTION_ID INTEGER, STATE CHAR(1), ORD INTEGER, PAGE_ORD INTEGER, DELIVERY_COUNT INTEGER, SCHED_DELIVERY INTEGER, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
+   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
+   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
+   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
+   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
+   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
+   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID INTEGER, RELIABLE CHAR(1), EXPIRATION INTEGER, TIMESTAMP INTEGER, PRIORITY INTEGER, HEADERS BLOB, PAYLOAD BLOB, CHANNEL_COUNT INTEGER, TYPE INTEGER, PRIMARY KEY (MESSAGE_ID))
+   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID INTEGER, BRANCH_QUAL RAW(254), FORMAT_ID INTEGER, GLOBAL_TXID RAW(254), PRIMARY KEY (TRANSACTION_ID))
+   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR2(255), NEXT_ID INTEGER, PRIMARY KEY(NAME))
+   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
+   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
+   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
+   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
+   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
+   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
+   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
+   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
+   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
+   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
+   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
+   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
+   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
+   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
+   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
+   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
+   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
+   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
+   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
+   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
+   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
+   MESSAGE_ID_COLUMN=MESSAGE_ID
+   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ? FOR UPDATE
+   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
+   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
+   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
+   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
+   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
+   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
+   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=? FOR UPDATE
+   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
+   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
+      ]]></attribute>
+      
+      <!-- The maximum number of parameters to include in a prepared statement -->
+                  
+      <attribute name="MaxParams">500</attribute>
+   </mbean>
+
+   <!-- Messaging Post Office MBean configuration
+        ========================================= -->
+   
+   <mbean code="org.jboss.messaging.core.jmx.MessagingPostOfficeService"
+      name="jboss.messaging:service=PostOffice"
+      xmbean-dd="xmdesc/MessagingPostOffice-xmbean.xml">
+            
+      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
+      
+      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
+      
+      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
+      
+      <!-- The name of the post office -->      
+                  
+      <attribute name="PostOfficeName">JMS post office</attribute>
+      
+      <!-- The datasource used by the post office to access it's binding information -->      
+                    
+      <attribute name="DataSource">java:/DefaultDS</attribute>
+      
+      <!-- If true will attempt to create tables and indexes on every start-up -->                  
+      
+      <attribute name="CreateTablesOnStartup">true</attribute>
+      
+      <attribute name="SqlProperties"><![CDATA[
+CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR2(255), NODE_ID INTEGER, QUEUE_NAME VARCHAR2(1023), COND VARCHAR2(1023), SELECTOR VARCHAR2(1023), CHANNEL_ID INTEGER, CLUSTERED CHAR(1))
+INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
+DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
+LOAD_BINDINGS=SELECT QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=?
+      ]]></attribute>
+      
+	  <!-- This post office is clustered. If you don't want a clustered post office then set to false -->
+      
+      <attribute name="Clustered">true</attribute>
+      
+      <!-- All the remaining properties only have to be specified if the post office is clustered.
+           You can safely comment them out if your post office is non clustered -->
+      
+      <!-- The JGroups group name that the post office will use -->          
+      
+      <attribute name="GroupName">MessagingPostOffice</attribute>
+      
+      <!-- Max time to wait for state to arrive when the post office joins the cluster -->            
+                  
+      <attribute name="StateTimeout">5000</attribute>
+      
+      <!-- Max time to wait for a synchronous call to node members using the MessageDispatcher -->            
+                  
+      <attribute name="CastTimeout">5000</attribute>
+      
+      <!-- Enable this when the JGroups multiplexer comes of age
+      <attribute name="ChannelFactoryName">jgroups.mux:name=Multiplexer</attribute>      
+      <attribute name="SyncChannelName">udp-sync</attribute>
+      <attribute name="AsyncChannelName">udp</attribute>
+      <attribute name="ChannelPartitionName">${jboss.partition.name:DefaultPartition}-JMS</attribute>
+      -->
+      
+      <!-- JGroups stack configuration for the data channel - used when casting messages across the cluster -->
+                              
+      <attribute name="AsyncChannelConfig">
+         <config>
+            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
+           mcast_port="45567" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
+           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
+            <AUTOCONF down_thread="false" up_thread="false"/>
+            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
+            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
+            <FD_SOCK down_thread="false" up_thread="false"/>
+            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
+            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
+            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
+                         retransmit_timeout="100,200,600,1200,2400,4800"/>
+            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
+            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
+            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
+            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
+            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
+         </config>
+      </attribute>
+      
+      <!-- JGroups stack configuration to use for the control channel - used for bind/unbind requests amongst others -->                       
+      
+      <attribute name="SyncChannelConfig">
+         <config>
+            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
+           mcast_port="45568" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
+           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
+            <AUTOCONF down_thread="false" up_thread="false"/>
+            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
+            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
+            <FD_SOCK down_thread="false" up_thread="false"/>
+            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
+            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
+            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
+                         retransmit_timeout="100,200,600,1200,2400,4800"/>
+            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
+            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
+            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
+            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
+            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
+            <pbcast.STATE_TRANSFER down_thread="false" up_thread="false"/>
+         </config>
+      </attribute>
+   </mbean>
+   
+   <!-- Messaging JMS User Manager MBean config
+        ======================================= -->
+      
+   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
+      name="jboss.messaging:service=JMSUserManager"
+      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR2(32) NOT NULL, PASSWD VARCHAR2(32) NOT NULL, CLIENTID VARCHAR2(128), PRIMARY KEY(USER_ID))
+CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR2(32) NOT NULL, USER_ID VARCHAR2(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
+SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
+POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
+      ]]></attribute>
+   </mbean>
+
+</server>
\ No newline at end of file

Deleted: trunk/src/etc/server/default/deploy/postgresql-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/postgresql-persistence-service.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/server/default/deploy/postgresql-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,101 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-     Postgresql non-clustered persistence deployment descriptor.
-
-     Tested with PostgresSQL 8.1.5
-
-     $Id$
- -->
-
-<server>
-
-   <mbean code="org.jboss.messaging.core.plugin.JDBCPersistenceManagerService"
-         name="jboss.messaging:service=PersistenceManager"
-         xmbean-dd="xmdesc/JDBCPersistenceManager-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="UsingBatchUpdates">true</attribute>
-       <attribute name="SqlProperties"><![CDATA[
-   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, DELIVERY_COUNT INTEGER, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
-   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
-   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
-   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
-   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
-   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
-   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY SMALLINT, HEADERS BYTEA, PAYLOAD BYTEA, CHANNEL_COUNT INTEGER, TYPE SMALLINT, PRIMARY KEY (MESSAGE_ID))
-   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID BIGINT, BRANCH_QUAL BYTEA, FORMAT_ID INTEGER, GLOBAL_TXID BYTEA, PRIMARY KEY (TRANSACTION_ID))
-   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))
-   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
-   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
-   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
-   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
-   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
-   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
-   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
-   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
-   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
-   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
-   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
-   SELECT_EXISTS_REF=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
-   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
-   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
-   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
-   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
-   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
-   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
-   MESSAGE_ID_COLUMN=MESSAGE_ID
-   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ? FOR UPDATE
-   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
-   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
-   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
-   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
-   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
-   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
-   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=? FOR UPDATE
-   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
-   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
-       ]]></attribute>
-
-         <attribute name="MaxParams">500</attribute>
-   </mbean>
-
-   <mbean code="org.jboss.messaging.core.plugin.DefaultPostOfficeService"
-      name="jboss.messaging:service=PostOffice"
-      xmbean-dd="xmdesc/DefaultPostOffice-xmbean.xml">
-      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
-      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-      <attribute name="PostOfficeName">JMS</attribute>
-      <attribute name="DataSource">java:/DefaultDS</attribute>
-      <attribute name="CreateTablesOnStartup">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID INTEGER, QUEUE_NAME VARCHAR(1023), COND VARCHAR(1023), SELECTOR VARCHAR(1023), CHANNEL_ID BIGINT, CLUSTERED CHAR(1))
-INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
-DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
-LOAD_BINDINGS=SELECT NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME  = ?
-      ]]></attribute>
-   </mbean>
-
-   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
-      name="jboss.messaging:service=JMSUserManager"
-      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
-CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
-SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
-      ]]></attribute>
-   </mbean>
-
-</server>
\ No newline at end of file

Copied: trunk/src/etc/server/default/deploy/postgresql-persistence-service.xml (from rev 2781, trunk/src/etc/server/default/deploy/clustered-postgresql-persistence-service.xml)
===================================================================
--- trunk/src/etc/server/default/deploy/postgresql-persistence-service.xml	                        (rev 0)
+++ trunk/src/etc/server/default/deploy/postgresql-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+     Postgresql persistence deployment descriptor.
+
+     Tested with PostgresSQL 8.1.5
+
+     $Id$
+ -->
+
+<server>
+
+   <!-- Persistence Manager MBean configuration
+       ======================================= -->
+   
+   <mbean code="org.jboss.messaging.core.jmx.JDBCPersistenceManagerService"
+      name="jboss.messaging:service=PersistenceManager"
+      xmbean-dd="xmdesc/JDBCPersistenceManager-xmbean.xml">
+      
+      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
+      
+      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
+      
+      <!-- The datasource to use for the persistence manager -->
+                    
+      <attribute name="DataSource">java:/DefaultDS</attribute>
+      
+      <!-- If true will attempt to create tables and indexes on every start-up -->
+                  
+      <attribute name="CreateTablesOnStartup">true</attribute>
+      
+      <!-- If true then will use JDBC batch updates -->
+                  
+      <attribute name="UsingBatchUpdates">true</attribute>
+      
+      <attribute name="SqlProperties"><![CDATA[
+   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, DELIVERY_COUNT INTEGER, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
+   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
+   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
+   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
+   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
+   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
+   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY SMALLINT, HEADERS BYTEA, PAYLOAD BYTEA, CHANNEL_COUNT INTEGER, TYPE SMALLINT, PRIMARY KEY (MESSAGE_ID))
+   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID BIGINT, BRANCH_QUAL BYTEA, FORMAT_ID INTEGER, GLOBAL_TXID BYTEA, PRIMARY KEY (TRANSACTION_ID))
+   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))
+   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
+   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
+   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
+   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
+   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
+   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
+   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
+   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
+   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
+   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
+   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
+   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
+   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
+   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
+   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
+   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
+   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
+   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
+   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
+   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
+   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
+   MESSAGE_ID_COLUMN=MESSAGE_ID
+   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ? FOR UPDATE
+   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
+   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
+   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
+   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
+   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
+   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
+   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=? FOR UPDATE
+   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
+   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
+      ]]></attribute>
+      
+      <!-- The maximum number of parameters to include in a prepared statement -->
+                  
+      <attribute name="MaxParams">500</attribute>
+   </mbean>
+
+   <!-- Messaging Post Office MBean configuration
+        ========================================= -->
+   
+   <mbean code="org.jboss.messaging.core.jmx.MessagingPostOfficeService"
+      name="jboss.messaging:service=PostOffice"
+      xmbean-dd="xmdesc/MessagingPostOffice-xmbean.xml">
+      
+      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
+      
+      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
+      
+      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
+      
+      <!-- The name of the post office -->      
+                  
+      <attribute name="PostOfficeName">JMS post office</attribute>
+      
+      <!-- The datasource used by the post office to access it's binding information -->                        
+      
+      <attribute name="DataSource">java:/DefaultDS</attribute>
+      
+      <!-- If true will attempt to create tables and indexes on every start-up -->              
+      
+      <attribute name="CreateTablesOnStartup">true</attribute>
+      
+      <attribute name="SqlProperties"><![CDATA[
+CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID INTEGER, QUEUE_NAME VARCHAR(1023), COND VARCHAR(1023), SELECTOR VARCHAR(1023), CHANNEL_ID BIGINT, CLUSTERED CHAR(1))
+INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
+DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
+LOAD_BINDINGS=SELECT QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=?
+      ]]></attribute>
+      
+	<!-- This post office is clustered. If you don't want a clustered post office then set to false -->
+      
+      <attribute name="Clustered">true</attribute>
+      
+      <!-- All the remaining properties only have to be specified if the post office is clustered.
+           You can safely comment them out if your post office is non clustered -->
+      
+      <!-- The JGroups group name that the post office will use -->          
+      
+      <attribute name="GroupName">MessagingPostOffice</attribute>
+      
+      <!-- Max time to wait for state to arrive when the post office joins the cluster -->                        
+      
+      <attribute name="StateTimeout">5000</attribute>
+      
+      <!-- Max time to wait for a synchronous call to node members using the MessageDispatcher -->                        
+      
+      <attribute name="CastTimeout">5000</attribute>
+      
+      <!-- Enable this when the JGroups multiplexer comes of age
+      <attribute name="ChannelFactoryName">jgroups.mux:name=Multiplexer</attribute>      
+      <attribute name="SyncChannelName">udp-sync</attribute>
+      <attribute name="AsyncChannelName">udp</attribute>
+      <attribute name="ChannelPartitionName">${jboss.partition.name:DefaultPartition}-JMS</attribute>
+      -->
+      
+      <!-- JGroups stack configuration for the data channel - used when casting messages across the cluster -->                        
+      
+      <attribute name="AsyncChannelConfig">
+         <config>
+            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
+           mcast_port="45567" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
+           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
+            <AUTOCONF down_thread="false" up_thread="false"/>
+            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
+            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
+            <FD_SOCK down_thread="false" up_thread="false"/>
+            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
+            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
+            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
+                         retransmit_timeout="100,200,600,1200,2400,4800"/>
+            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
+            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
+            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
+            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
+            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
+         </config>
+      </attribute>
+      
+      <!-- JGroups stack configuration to use for the control channel - used for bind/unbind requests amongst others -->                       
+      
+      <attribute name="SyncChannelConfig">
+         <config>
+            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
+           mcast_port="45568" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
+           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
+            <AUTOCONF down_thread="false" up_thread="false"/>
+            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
+            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
+            <FD_SOCK down_thread="false" up_thread="false"/>
+            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
+            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
+            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
+                         retransmit_timeout="100,200,600,1200,2400,4800"/>
+            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
+            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
+            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
+            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
+            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
+            <pbcast.STATE_TRANSFER down_thread="false" up_thread="false"/>
+         </config>
+      </attribute>
+   </mbean>
+   
+   <!-- Messaging JMS User Manager MBean config
+        ======================================= -->
+      
+   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
+      name="jboss.messaging:service=JMSUserManager"
+      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
+CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
+SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
+POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
+      ]]></attribute>
+   </mbean>
+
+</server>
\ No newline at end of file

Deleted: trunk/src/etc/server/default/deploy/sybase-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/sybase-persistence-service.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/server/default/deploy/sybase-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,101 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-     Sybase non-clustered persistence deployment descriptor.
-
-     Tested with Sybase Adaptive Server Enterprise 12.5.2
-
-     $Id$
- -->
-
-<server>
-
-   <mbean code="org.jboss.messaging.core.plugin.JDBCPersistenceManagerService"
-         name="jboss.messaging:service=PersistenceManager"
-         xmbean-dd="xmdesc/JDBCPersistenceManager-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="UsingBatchUpdates">true</attribute>
-         <attribute name="UsingTrailingByte">true</attribute>
-         <attribute name="SqlProperties"><![CDATA[
-   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID DECIMAL(19, 0), MESSAGE_ID DECIMAL(19, 0), TRANSACTION_ID DECIMAL(19, 0) NULL, STATE CHAR(1), ORD DECIMAL(19, 0), PAGE_ORD DECIMAL(19, 0) NULL, DELIVERY_COUNT INTEGER, SCHED_DELIVERY DECIMAL(19, 0), PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
-   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
-   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
-   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
-   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
-   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
-   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID DECIMAL(19, 0), RELIABLE CHAR(1), EXPIRATION DECIMAL(19, 0), TIMESTAMP DECIMAL(19, 0), PRIORITY TINYINT, HEADERS IMAGE NULL, PAYLOAD IMAGE NULL, CHANNEL_COUNT INTEGER, TYPE TINYINT, PRIMARY KEY (MESSAGE_ID))
-   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID DECIMAL(19, 0), BRANCH_QUAL VARBINARY(254) NULL, FORMAT_ID INTEGER NULL, GLOBAL_TXID VARBINARY(254) NULL, PRIMARY KEY (TRANSACTION_ID))
-   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID DECIMAL(19, 0), PRIMARY KEY(NAME))
-   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
-   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
-   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
-   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
-   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
-   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
-   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
-   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
-   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
-   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
-   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
-   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
-   SELECT_EXISTS_REF=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
-   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
-   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
-   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
-   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
-   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
-   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
-   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
-   MESSAGE_ID_COLUMN=MESSAGE_ID
-   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG HOLDLOCK WHERE MESSAGE_ID = ?
-   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
-   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
-   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
-   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
-   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
-   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
-   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER HOLDLOCK WHERE NAME=?
-   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
-   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
-         ]]></attribute>
-         <attribute name="MaxParams">500</attribute>
-   </mbean>
-
-   <mbean code="org.jboss.messaging.core.plugin.DefaultPostOfficeService"
-      name="jboss.messaging:service=PostOffice"
-      xmbean-dd="xmdesc/DefaultPostOffice-xmbean.xml">
-      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
-      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-      <attribute name="PostOfficeName">JMS</attribute>
-      <attribute name="DataSource">java:/DefaultDS</attribute>
-      <attribute name="CreateTablesOnStartup">true</attribute>
-      <attribute name="SqlProperties"><![CDATA[
-CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID SMALLINT, QUEUE_NAME VARCHAR(1023), COND VARCHAR(1023), SELECTOR VARCHAR(1023) NULL, CHANNEL_ID INTEGER, CLSTERED CHAR(1))
-INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
-DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
-LOAD_BINDINGS=SELECT NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME  = ?
-      ]]></attribute>
-   </mbean>
-
-   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
-      name="jboss.messaging:service=JMSUserManager"
-      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
-CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
-SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
-      ]]></attribute>
-   </mbean>
-
-</server>

Copied: trunk/src/etc/server/default/deploy/sybase-persistence-service.xml (from rev 2781, trunk/src/etc/server/default/deploy/clustered-sybase-persistence-service.xml)
===================================================================
--- trunk/src/etc/server/default/deploy/sybase-persistence-service.xml	                        (rev 0)
+++ trunk/src/etc/server/default/deploy/sybase-persistence-service.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+     Sybase persistence deployment descriptor.
+
+     Tested with Sybase Adaptive Server Enterprise 12.5.2
+
+     $Id$
+ -->
+
+<server>
+
+   <!-- Persistence Manager MBean configuration
+       ======================================= -->   
+
+   <mbean code="org.jboss.messaging.core.jmx.JDBCPersistenceManagerService"
+      name="jboss.messaging:service=PersistenceManager"
+      xmbean-dd="xmdesc/JDBCPersistenceManager-xmbean.xml">
+      
+      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
+      
+      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
+            
+      <!-- The datasource to use for the persistence manager -->
+                                
+      <attribute name="DataSource">java:/DefaultDS</attribute>
+      
+      <!-- If true will attempt to create tables and indexes on every start-up -->
+                  
+      <attribute name="CreateTablesOnStartup">true</attribute>
+      
+      <!-- If true then will use JDBC batch updates -->
+                  
+      <attribute name="UsingBatchUpdates">true</attribute>
+      
+      <!-- If true then will add a trailing byte to all byte arrays otherwise Sybase truncates them
+           Only known to be necessary for Sybase -->
+                  
+      <attribute name="UsingTrailingByte">true</attribute>
+      
+      <attribute name="SqlProperties"><![CDATA[
+   CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID DECIMAL(19, 0), MESSAGE_ID DECIMAL(19, 0), TRANSACTION_ID DECIMAL(19, 0) NULL, STATE CHAR(1), ORD DECIMAL(19, 0), PAGE_ORD DECIMAL(19, 0) NULL, DELIVERY_COUNT INTEGER, SCHED_DELIVERY DECIMAL(19, 0), PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
+   CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
+   CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
+   CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
+   CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
+   CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
+   CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID DECIMAL(19, 0), RELIABLE CHAR(1), EXPIRATION DECIMAL(19, 0), TIMESTAMP DECIMAL(19, 0), PRIORITY TINYINT, HEADERS IMAGE NULL, PAYLOAD IMAGE NULL, CHANNEL_COUNT INTEGER, TYPE TINYINT, PRIMARY KEY (MESSAGE_ID))
+   CREATE_TRANSACTION=CREATE TABLE JBM_TX (TRANSACTION_ID DECIMAL(19, 0), BRANCH_QUAL VARBINARY(254) NULL, FORMAT_ID INTEGER NULL, GLOBAL_TXID VARBINARY(254) NULL, PRIMARY KEY (TRANSACTION_ID))
+   CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID DECIMAL(19, 0), PRIMARY KEY(NAME))
+   INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
+   DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
+   UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
+   UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
+   COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
+   COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
+   ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
+   ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
+   LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
+   LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
+   LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
+   UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
+   SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
+   SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
+   UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
+   UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
+   LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
+   INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
+   INC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?
+   DEC_CHANNEL_COUNT=UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?
+   DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT=0
+   MESSAGE_ID_COLUMN=MESSAGE_ID
+   MESSAGE_EXISTS=SELECT MESSAGE_ID FROM JBM_MSG HOLDLOCK WHERE MESSAGE_ID = ?
+   INSERT_TRANSACTION=INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
+   DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?
+   SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX
+   SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
+   SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
+   UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
+   SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER HOLDLOCK WHERE NAME=?
+   INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
+   SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
+      ]]></attribute>
+      
+      <!-- The maximum number of parameters to include in a prepared statement -->
+                  
+      <attribute name="MaxParams">500</attribute>
+   </mbean>
+
+   <!-- Messaging Post Office MBean configuration
+        ========================================= -->
+   
+   <mbean code="org.jboss.messaging.core.jmx.MessagingPostOfficeService"
+      name="jboss.messaging:service=PostOffice"
+      xmbean-dd="xmdesc/MessagingPostOffice-xmbean.xml">
+      
+      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
+      
+      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
+      
+      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
+      
+      <!-- The name of the post office -->      
+                  
+      <attribute name="PostOfficeName">JMS post office</attribute>
+      
+      <!-- The datasource used by the post office to access it's binding information -->                              
+      
+      <attribute name="DataSource">java:/DefaultDS</attribute>
+      
+      <!-- If true will attempt to create tables and indexes on every start-up -->
+                        
+      <attribute name="CreateTablesOnStartup">true</attribute>
+      
+      <attribute name="SqlProperties"><![CDATA[
+CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID SMALLINT, QUEUE_NAME VARCHAR(1023), COND VARCHAR(1023), SELECTOR VARCHAR(1023) NULL, CHANNEL_ID INTEGER, CLSTERED CHAR(1))
+INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLSTERED) VALUES (?, ?, ?, ?, ?, ?, ?)
+DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
+LOAD_BINDINGS=SELECT QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=?
+      ]]></attribute>
+      
+	  <!-- This post office is clustered. If you don't want a clustered post office then set to false -->
+      
+      <attribute name="Clustered">true</attribute>
+      
+      <!-- All the remaining properties only have to be specified if the post office is clustered.
+           You can safely comment them out if your post office is non clustered -->
+      
+      <!-- The JGroups group name that the post office will use -->         
+      
+      <attribute name="GroupName">MessagingPostOffice</attribute>
+      
+      <!-- Max time to wait for state to arrive when the post office joins the cluster -->            
+                  
+      <attribute name="StateTimeout">5000</attribute>
+      
+      <!-- Max time to wait for a synchronous call to node members using the MessageDispatcher -->            
+                  
+      <attribute name="CastTimeout">5000</attribute>
+      
+      <!-- Enable this when the JGroups multiplexer comes of age
+      <attribute name="ChannelFactoryName">jgroups.mux:name=Multiplexer</attribute>      
+      <attribute name="SyncChannelName">udp-sync</attribute>
+      <attribute name="AsyncChannelName">udp</attribute>
+      <attribute name="ChannelPartitionName">${jboss.partition.name:DefaultPartition}-JMS</attribute>
+      -->
+      
+      <!-- JGroups stack configuration for the data channel - used when casting messages across the cluster -->
+                           
+      <attribute name="AsyncChannelConfig">
+         <config>
+            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
+           mcast_port="45567" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
+           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
+            <AUTOCONF down_thread="false" up_thread="false"/>
+            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
+            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
+            <FD_SOCK down_thread="false" up_thread="false"/>
+            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
+            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
+            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
+                         retransmit_timeout="100,200,600,1200,2400,4800"/>
+            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
+            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
+            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
+            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
+            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
+         </config>
+      </attribute>
+      
+      <!-- JGroups stack configuration to use for the control channel - used for bind/unbind requests amongst others -->           
+                  
+      <attribute name="SyncChannelConfig">
+         <config>
+            <UDP mcast_recv_buf_size="500000" down_thread="false" ip_mcast="true" mcast_send_buf_size="32000"
+           mcast_port="45568" ucast_recv_buf_size="500000" use_incoming_packet_handler="false"
+           mcast_addr="228.8.8.8" use_outgoing_packet_handler="true" loopback="true" ucast_send_buf_size="32000" ip_ttl="32" />
+            <AUTOCONF down_thread="false" up_thread="false"/>
+            <PING timeout="2000" down_thread="false" num_initial_members="3" up_thread="false"/>
+            <MERGE2 max_interval="10000" down_thread="false" min_interval="5000" up_thread="false"/>
+            <FD_SOCK down_thread="false" up_thread="false"/>
+            <FD timeout="20000" max_tries="3" down_thread="false" up_thread="false" shun="true"/>
+            <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
+            <pbcast.NAKACK max_xmit_size="8192" down_thread="false" use_mcast_xmit="true" gc_lag="50" up_thread="false"
+                         retransmit_timeout="100,200,600,1200,2400,4800"/>
+            <UNICAST timeout="1200,2400,3600" down_thread="false" up_thread="false"/>
+            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="20000" down_thread="false" max_bytes="0" up_thread="false"/>
+            <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
+            <VIEW_SYNC avg_send_interval="60000" down_thread="false" up_thread="false" />
+            <pbcast.GMS print_local_addr="true" join_timeout="3000" down_thread="false" join_retry_timeout="2000" up_thread="false" shun="true"/>
+            <pbcast.STATE_TRANSFER down_thread="false" up_thread="false"/>
+         </config>
+      </attribute>
+   </mbean>
+   
+   <!-- Messaging JMS User Manager MBean config
+        ======================================= -->
+      
+   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
+      name="jboss.messaging:service=JMSUserManager"
+      xmbean-dd="xmdesc/JMSUserManager-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 JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
+CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
+SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
+POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
+      ]]></attribute>
+   </mbean>
+
+</server>

Modified: trunk/src/etc/xmdesc/Bridge-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/Bridge-xmbean.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/xmdesc/Bridge-xmbean.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -14,7 +14,7 @@
    <attribute access="read-only" getMethod="getInstance">
       <description>Gets the underlying instance</description>
       <name>Instance</name>
-      <type>org.jboss.messaging.core.plugin.contract.MessagingComponent</type>
+      <type>org.jboss.messaging.core.contract.MessagingComponent</type>
    </attribute>
 
 	<attribute access="read-write" getMethod="getSourceProviderLoader"

Deleted: trunk/src/etc/xmdesc/ClusteredPostOffice-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/ClusteredPostOffice-xmbean.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/xmdesc/ClusteredPostOffice-xmbean.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,168 +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>An clustered post-office</description>
-   <class>org.jboss.messaging.core.plugin.ClusteredPostOfficeService</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>org.jboss.messaging.core.plugin.contract.MessagingComponent</type>
-   </attribute>
-
-   <attribute access="read-only" getMethod="getNodeIDView">
-      <description>The set containing cluster group members' node IDs</description>
-      <name>NodeIDView</name>
-      <type>java.util.Set</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>
-   
-   <attribute access="read-write" getMethod="getPostOfficeName" setMethod="setPostOfficeName">
-      <description>The name of the post office</description>
-      <name>PostOfficeName</name>
-      <type>java.lang.String</type>
-   </attribute> 
-   
-   <attribute access="read-write" getMethod="getServerPeer" setMethod="setServerPeer">
-      <description>The ObjectName of the server peer this destination was deployed on</description>
-      <name>ServerPeer</name>
-      <type>javax.management.ObjectName</type>
-   </attribute> 
-   
-   <attribute access="read-write" getMethod="getGroupName" setMethod="setGroupName">
-      <description>The name of the JGroups group to use</description>
-      <name>GroupName</name>
-      <type>java.lang.String</type>
-   </attribute>   
-   
-   <attribute access="read-write" getMethod="getMessagePullPolicy" setMethod="setMessagePullPolicy">
-      <description>The fully qualified class name of the class to use to implement the message pull policy for rebalancing</description>
-      <name>MessagePullPolicy</name>
-      <type>java.lang.String</type>
-   </attribute> 
-   
-   <attribute access="read-write" getMethod="getClusterRouterFactory" setMethod="setClusterRouterFactory">
-      <description>The fully qualified class name of the class to use to implement the factory that generates cluster routers</description>
-      <name>ClusterRouterFactory</name>
-      <type>java.lang.String</type>
-   </attribute>   
-   
-   <attribute access="read-write" getMethod="getStateTimeout" setMethod="setStateTimeout">
-      <description>Timeout for getState()</description>
-      <name>StateTimeout</name>
-      <type>long</type>
-   </attribute>
-   
-   <attribute access="read-write" getMethod="getCastTimeout" setMethod="setCastTimeout">
-      <description>Timeout for getState()</description>
-      <name>CastTimeout</name>
-      <type>long</type>
-   </attribute>   
-   
-   <attribute access="read-write" getMethod="getStatsSendPeriod" setMethod="setStatsSendPeriod">
-      <description>The period in milliseconds between a post office casting it's statistics across the cluster</description>
-      <name>StatsSendPeriod</name>
-      <type>long</type>
-   </attribute>    
-   
-   <attribute access="read-write" getMethod="getSyncChannelConfig" setMethod="setSyncChannelConfig">
-      <description>The JGroups stack configuration for the synchronous channel</description>
-      <name>SyncChannelConfig</name>
-      <type>org.w3c.dom.Element</type>
-   </attribute>
-   
-   <attribute access="read-write" getMethod="getAsyncChannelConfig" setMethod="setAsyncChannelConfig">
-      <description>The JGroups stack configuration for the asynchronous channel</description>
-      <name>AsyncChannelConfig</name>
-      <type>org.w3c.dom.Element</type>
-   </attribute>   
-   
-   <attribute access="read-write" getMethod="getServerPeer" setMethod="setServerPeer">
-      <description>The ObjectName of the server peer this destination was deployed on</description>
-      <name>ServerPeer</name>
-      <type>javax.management.ObjectName</type>
-   </attribute>
-
-   <attribute access="read-write" getMethod="getChannelFactoryName" setMethod="setChannelFactoryName">
-      <description>The ObjectName of the JGroups Multiplexer used to create JChannels</description>
-      <name>ChannelFactoryName</name>
-      <type>javax.management.ObjectName</type>
-   </attribute>
-
-   <attribute access="read-write" getMethod="getSyncChannelName" setMethod="setSyncChannelName">
-      <description>The name of the stack used on multiplexer for Sync Channels</description>
-      <name>SyncChannelName</name>
-      <type>java.lang.String</type>
-   </attribute>
-
-   <attribute access="read-write" getMethod="getAsyncChannelName" setMethod="setAsyncChannelName">
-      <description>The name of the stack used on multiplexer for Async Channels</description>
-      <name>AsyncChannelName</name>
-      <type>java.lang.String</type>
-   </attribute>
-
-   <attribute access="read-write" getMethod="getChannelPartitionName" setMethod="setChannelPartitionName">
-      <description>The partition name used to identify JMS/Postoffice on the JGroups Multiplexor</description>
-      <name>ChannelPartitionName</name>
-      <type>java.lang.String</type>
-   </attribute>
-   
-   <attribute access="read-write" getMethod="getThreadPoolSize" setMethod="setThreadPoolSize">
-      <description>The size of the thread pool used to perform various asynchronous clustering operations</description>
-      <name>ThreadPoolSize</name>
-      <type>int</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

Deleted: trunk/src/etc/xmdesc/DefaultPostOffice-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/DefaultPostOffice-xmbean.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/xmdesc/DefaultPostOffice-xmbean.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,78 +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>An simple non-clustered post-office</description>
-   <class>org.jboss.messaging.core.plugin.DefaultPostOfficeService</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>org.jboss.messaging.core.plugin.contract.MessagingComponent</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>
-   
-   <attribute access="read-write" getMethod="getPostOfficeName" setMethod="setPostOfficeName">
-      <description>The name of the post office</description>
-      <name>PostOfficeName</name>
-      <type>java.lang.String</type>
-   </attribute> 
-   
-   <attribute access="read-write" getMethod="getServerPeer" setMethod="setServerPeer">
-      <description>The ObjectName of the server peer this destination was deployed on</description>
-      <name>ServerPeer</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/etc/xmdesc/JDBCPersistenceManager-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/JDBCPersistenceManager-xmbean.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/xmdesc/JDBCPersistenceManager-xmbean.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -5,7 +5,7 @@
 
 <mbean>
    <description>A JDBC persistence manager</description>
-   <class>org.jboss.messaging.core.plugin.JDBCPersistenceManagerService</class>
+   <class>org.jboss.messaging.core.jmx.JDBCPersistenceManagerService</class>
 
    <!-- Managed constructors -->
 
@@ -14,7 +14,7 @@
    <attribute access="read-only" getMethod="getInstance">
       <description>The instance to plug into the server peer</description>
       <name>Instance</name>
-      <type>org.jboss.messaging.core.plugin.contract.MessagingComponent</type>
+      <type>org.jboss.messaging.core.contract.MessagingComponent</type>
    </attribute>
 
    <attribute access="read-write" getMethod="getDataSource" setMethod="setDataSource">
@@ -87,4 +87,4 @@
       <name>destroy</name>
    </operation>
 
-</mbean>
\ No newline at end of file
+</mbean>

Modified: trunk/src/etc/xmdesc/JMSUserManager-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/JMSUserManager-xmbean.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/xmdesc/JMSUserManager-xmbean.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -14,7 +14,7 @@
    <attribute access="read-only" getMethod="getInstance">
       <description>The instance to plug into the server peer</description>
       <name>Instance</name>
-      <type>org.jboss.messaging.core.plugin.contract.MessagingComponent</type>
+      <type>org.jboss.messaging.core.contract.MessagingComponent</type>
    </attribute>
 
    <attribute access="read-write" getMethod="getDataSource" setMethod="setDataSource">

Copied: trunk/src/etc/xmdesc/MessagingPostOffice-xmbean.xml (from rev 2781, trunk/src/etc/xmdesc/ClusteredPostOffice-xmbean.xml)
===================================================================
--- trunk/src/etc/xmdesc/MessagingPostOffice-xmbean.xml	                        (rev 0)
+++ trunk/src/etc/xmdesc/MessagingPostOffice-xmbean.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,150 @@
+<?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 messaging post-office</description>
+   <class>org.jboss.messaging.core.jmx.MessagingPostOfficeService</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>org.jboss.messaging.core.contract.MessagingComponent</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>
+   
+   <attribute access="read-write" getMethod="getPostOfficeName" setMethod="setPostOfficeName">
+      <description>The name of the post office</description>
+      <name>PostOfficeName</name>
+      <type>java.lang.String</type>
+   </attribute> 
+   
+   <attribute access="read-write" getMethod="getServerPeer" setMethod="setServerPeer">
+      <description>The ObjectName of the server peer this destination was deployed on</description>
+      <name>ServerPeer</name>
+      <type>javax.management.ObjectName</type>
+   </attribute> 
+   
+   <attribute access="read-write" getMethod="getGroupName" setMethod="setGroupName">
+      <description>The name of the JGroups group to use</description>
+      <name>GroupName</name>
+      <type>java.lang.String</type>
+   </attribute>   
+           
+   <attribute access="read-write" getMethod="getStateTimeout" setMethod="setStateTimeout">
+      <description>Timeout for getState()</description>
+      <name>StateTimeout</name>
+      <type>long</type>
+   </attribute>
+   
+   <attribute access="read-write" getMethod="getCastTimeout" setMethod="setCastTimeout">
+      <description>Timeout for getState()</description>
+      <name>CastTimeout</name>
+      <type>long</type>
+   </attribute> 
+   
+   <attribute access="read-write" getMethod="isClustered" setMethod="setClustered">
+      <description>Is this post office clustered?</description>
+      <name>Clustered</name>
+      <type>boolean</type>
+   </attribute>   
+      
+   <attribute access="read-write" getMethod="getSyncChannelConfig" setMethod="setSyncChannelConfig">
+      <description>The JGroups stack configuration for the synchronous channel</description>
+      <name>SyncChannelConfig</name>
+      <type>org.w3c.dom.Element</type>
+   </attribute>
+   
+   <attribute access="read-write" getMethod="getAsyncChannelConfig" setMethod="setAsyncChannelConfig">
+      <description>The JGroups stack configuration for the asynchronous channel</description>
+      <name>AsyncChannelConfig</name>
+      <type>org.w3c.dom.Element</type>
+   </attribute>   
+   
+   <attribute access="read-write" getMethod="getServerPeer" setMethod="setServerPeer">
+      <description>The ObjectName of the server peer this destination was deployed on</description>
+      <name>ServerPeer</name>
+      <type>javax.management.ObjectName</type>
+   </attribute>
+
+   <attribute access="read-write" getMethod="getChannelFactoryName" setMethod="setChannelFactoryName">
+      <description>The ObjectName of the JGroups Multiplexer used to create JChannels</description>
+      <name>ChannelFactoryName</name>
+      <type>javax.management.ObjectName</type>
+   </attribute>
+
+   <attribute access="read-write" getMethod="getSyncChannelName" setMethod="setSyncChannelName">
+      <description>The name of the stack used on multiplexer for Sync Channels</description>
+      <name>SyncChannelName</name>
+      <type>java.lang.String</type>
+   </attribute>
+
+   <attribute access="read-write" getMethod="getAsyncChannelName" setMethod="setAsyncChannelName">
+      <description>The name of the stack used on multiplexer for Async Channels</description>
+      <name>AsyncChannelName</name>
+      <type>java.lang.String</type>
+   </attribute>
+
+   <attribute access="read-write" getMethod="getChannelPartitionName" setMethod="setChannelPartitionName">
+      <description>The partition name used to identify JMS/Postoffice on the JGroups Multiplexor</description>
+      <name>ChannelPartitionName</name>
+      <type>java.lang.String</type>
+   </attribute>
+   
+   <attribute access="read-only" getMethod="getNodeIDView">
+      <description>Get the set of nodes in the cluster</description>
+      <name>NodeIDView</name>
+      <type>java.util.Set</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/Queue-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/Queue-xmbean.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/xmdesc/Queue-xmbean.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -158,7 +158,7 @@
    <attribute access="read-only" getMethod="getInstance">
       <description>The instance to be accessed by select plugins via a typed hard reference</description>
       <name>Instance</name>
-      <type>org.jboss.messaging.core.plugin.contract.MessagingComponent</type>
+      <type>org.jboss.messaging.core.contract.MessagingComponent</type>
    </attribute>
    
    <!-- Managed operations -->

Modified: trunk/src/etc/xmdesc/ServerPeer-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/ServerPeer-xmbean.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/xmdesc/ServerPeer-xmbean.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -33,19 +33,7 @@
       <name>JMSUserManager</name>
       <type>javax.management.ObjectName</type>
    </attribute>   
-   
-   <attribute access="read-write" getMethod="getDefaultDLQ" setMethod="setDefaultDLQ">
-      <description>The ObjectName of the default DLQ - used when an individual queue does not specify a DLQ</description>
-      <name>DefaultDLQ</name>
-      <type>javax.management.ObjectName</type>
-   </attribute>  
-   
-   <attribute access="read-write" getMethod="getDefaultExpiryQueue" setMethod="setDefaultExpiryQueue">
-      <description>The ObjectName of the default expiry queue - used when an individual queue does not specify an expiry queue</description>
-      <name>DefaultExpiryQueue</name>
-      <type>javax.management.ObjectName</type>
-   </attribute>    
-     
+         
    <!-- instance access -->
 
    <attribute access="read-only" getMethod="getInstance">
@@ -97,7 +85,37 @@
       <name>ProviderMinorVersion</name>
       <type>int</type>
    </attribute>
+   
+   <attribute access="read-only" getMethod="getDestinations">
+      <description>Returns a Set of javax.jms.Destinations (Queues and Topics) containing the current active destinations</description>
+      <name>Destinations</name>
+      <type>java.util.Set</type>
+   </attribute>
+   
+   <attribute access="read-only" getMethod="getMessageCounters">
+      <description>The message counters</description>
+      <name>MessageCounters</name>
+      <type>java.util.List</type>
+   </attribute>
 
+   <attribute access="read-only" getMethod="getMessageStatistics">
+      <description>The message statistics</description>
+      <name>MessageStatistics</name>
+      <type>java.util.List</type>
+   </attribute>
+      
+   <attribute access="read-write" getMethod="getDefaultDLQ" setMethod="setDefaultDLQ">
+      <description>The ObjectName of the default DLQ - used when an individual queue does not specify a DLQ</description>
+      <name>DefaultDLQ</name>
+      <type>javax.management.ObjectName</type>
+   </attribute>  
+   
+   <attribute access="read-write" getMethod="getDefaultExpiryQueue" setMethod="setDefaultExpiryQueue">
+      <description>The ObjectName of the default expiry queue - used when an individual queue does not specify an expiry queue</description>
+      <name>DefaultExpiryQueue</name>
+      <type>javax.management.ObjectName</type>
+   </attribute>   
+
    <attribute access="read-write" getMethod="getServerPeerID" setMethod="setServerPeerID">
       <description>The ID of the ServerPeer. Must be unique per JBoss instance</description>
       <name>ServerPeerID</name>
@@ -116,12 +134,6 @@
       <type>java.lang.String</type>
    </attribute>
 
-   <attribute access="read-only" getMethod="getDestinations">
-      <description>Returns a Set of javax.jms.Destinations (Queues and Topics) containing the current active destinations</description>
-      <name>Destinations</name>
-      <type>java.util.Set</type>
-   </attribute>
-
    <attribute access="read-write" getMethod="getSecurityDomain" setMethod="setSecurityDomain">
       <description>The Security Domain to be used by the Server Peer</description>
       <name>SecurityDomain</name>
@@ -158,30 +170,36 @@
       <type>long</type>
    </attribute>  
    
-   <attribute access="read-write" getMethod="getQueueStatsSamplePeriod" setMethod="setQueueStatsSamplePeriod">
-      <description>The period between which queue statistics are obtained</description>
-      <name>QueueStatsSamplePeriod</name>
+   <attribute access="read-write" getMethod="getMessageCounterSamplePeriod" setMethod="setMessageCounterSamplePeriod">
+      <description>The period between which the message counter manager enquires for statistics from queues</description>
+      <name>MessageCounterSamplePeriod</name>
       <type>long</type>
    </attribute> 
    
+   <attribute access="read-write" getMethod="getClusterPullConnectionFactoryName" setMethod="setClusterPullConnectionFactoryName">
+      <description>The name of the connection factory used to create connections to pull messages from one node to another</description>
+      <name>ClusterPullConnectionFactoryName</name>
+      <type>java.lang.String</type>
+   </attribute> 
+   
+   <attribute access="read-write" getMethod="isUseXAForMessagePull" setMethod="setUseXAForMessagePull">
+      <description>When pulling persistent messages from a remote durable queue to a local one, should XA be used?</description>
+      <name>UseXAForMessagePull</name>
+      <type>boolean</type>
+   </attribute>  
+   
+   <attribute access="read-write" getMethod="isDefaultPreserveOrdering" setMethod="setDefaultPreserveOrdering">
+      <description>When pulling messages do we need to preserve the ordering of messages consumed from a particular producer, for a particular consumer?</description>
+      <name>DefaultPreserveOrdering</name>
+      <type>boolean</type>
+   </attribute>    
+   
    <attribute access="read-write" getMethod="getDefaultMessageCounterHistoryDayLimit" setMethod="setDefaultMessageCounterHistoryDayLimit">
       <description>The default max number of messages per day in message counter history</description>
       <name>DefaultMessageCounterHistoryDayLimit</name>
       <type>int</type>
    </attribute>
 
-   <attribute access="read-only" getMethod="getMessageCounters">
-      <description>The message counters</description>
-      <name>MessageCounters</name>
-      <type>java.util.List</type>
-   </attribute>
-
-   <attribute access="read-only" getMethod="getMessageStatistics">
-      <description>The message statistics</description>
-      <name>MessageStatistics</name>
-      <type>java.util.List</type>
-   </attribute>
-
    <!-- Managed operations -->
 
    <operation>
@@ -393,4 +411,4 @@
    </operation>      
    
 
-</mbean>
\ No newline at end of file
+</mbean>

Modified: trunk/src/etc/xmdesc/Topic-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/Topic-xmbean.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/etc/xmdesc/Topic-xmbean.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -169,7 +169,7 @@
    <attribute access="read-only" getMethod="getInstance">
       <description>The instance to be accessed by select plugins via a typed hard reference</description>
       <name>Instance</name>
-      <type>org.jboss.messaging.core.plugin.contract.MessagingComponent</type>
+      <type>org.jboss.messaging.core.contract.MessagingComponent</type>
    </attribute>
 
    <!-- Managed operations -->

Modified: trunk/src/main/org/jboss/jms/client/JBossConnection.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/JBossConnection.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/client/JBossConnection.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -271,22 +271,6 @@
       return new JBossSession(sessionDelegate, type);
    }
 
-   // Temporarily commented out as it seems to produce random test failures
-   // See http://jira.jboss.org/jira/browse/JBMESSAGING-548
-   
-//   protected void finalize() throws Throwable
-//   {
-//      super.finalize();
-//
-//      // If a user hasn't explicitly closed the connection due to sloppy programming then
-//      // we close it here
-//
-//      if (!delegate.isClosed())
-//      {
-//         close();
-//      }
-//   }
-
    // Private --------------------------------------------------------------------------------------
 
    // Inner classes --------------------------------------------------------------------------------

Modified: trunk/src/main/org/jboss/jms/client/JBossConnectionConsumer.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/JBossConnectionConsumer.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/client/JBossConnectionConsumer.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -100,6 +100,8 @@
    
    private String queueName;
    
+   private boolean shouldAck;
+   
    // Static --------------------------------------------------------
    
    // Constructors --------------------------------------------------
@@ -116,11 +118,11 @@
          this.maxMessages = 1;
       }
 
-      // Create a consumer. The MessageCallbackhandler knows we are a connection consumer so will
+      // Create a consumer. The ClientConsumer knows we are a connection consumer so will
       // not call pre or postDeliver so messages won't be acked, or stored in session/tx.
       sess = conn.createSessionDelegate(false, Session.CLIENT_ACKNOWLEDGE, false);
 
-      cons = sess.createConsumerDelegate(dest, messageSelector, false, subName, true);
+      cons = sess.createConsumerDelegate(dest, messageSelector, false, subName, true, true);
 
       ConsumerState state = (ConsumerState)((DelegateSupport)cons).getState();
 
@@ -128,6 +130,8 @@
         
       this.maxDeliveries = state.getMaxDeliveries();
       
+      shouldAck = state.isShouldAck();      
+            
       if (subName != null)
       {
          queueName = MessageQueueNameHelper.createSubscriptionName(conn.getClientID(), subName);
@@ -283,7 +287,7 @@
                for (int i = 0; i < mesList.size(); i++)
                {
                   MessageProxy m = (MessageProxy)mesList.get(i);
-                  session.addAsfMessage(m, consumerID, queueName, maxDeliveries, sess);
+                  session.addAsfMessage(m, consumerID, queueName, maxDeliveries, sess, shouldAck);
                   if (trace) { log.trace("added " + m + " to session"); }
                }
 

Modified: trunk/src/main/org/jboss/jms/client/JBossSession.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/JBossSession.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/client/JBossSession.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -235,7 +235,7 @@
       log.debug("attempting to create consumer for destination:" + d + (messageSelector == null ? "" : ", messageSelector: " + messageSelector) + (noLocal ? ", noLocal = true" : ""));
 
       ConsumerDelegate cd = delegate.
-         createConsumerDelegate((JBossDestination)d, messageSelector, noLocal, null, false);
+         createConsumerDelegate((JBossDestination)d, messageSelector, noLocal, null, false, true);
 
       return new JBossMessageConsumer(cd);
    }
@@ -277,7 +277,7 @@
       }
 
       ConsumerDelegate cd =
-         delegate.createConsumerDelegate((JBossTopic)topic, null, false, name, false);
+         delegate.createConsumerDelegate((JBossTopic)topic, null, false, name, false, true);
 
       return new JBossMessageConsumer(cd);
    }
@@ -307,7 +307,7 @@
       }
 
       ConsumerDelegate cd = delegate.
-         createConsumerDelegate((JBossTopic)topic, messageSelector, noLocal, name, false);
+         createConsumerDelegate((JBossTopic)topic, messageSelector, noLocal, name, false, true);
 
       return new JBossMessageConsumer(cd);
    }
@@ -463,9 +463,9 @@
     * with messages to be processed by the session's run() method
     */
    void addAsfMessage(MessageProxy m, int consumerID, String queueName, int maxDeliveries,
-                      SessionDelegate connectionConsumerSession)
+                      SessionDelegate connectionConsumerSession, boolean shouldAck)
    {
-      delegate.addAsfMessage(m, consumerID, queueName, maxDeliveries, connectionConsumerSession);
+      delegate.addAsfMessage(m, consumerID, queueName, maxDeliveries, connectionConsumerSession, shouldAck);
    }
       
    // Protected -----------------------------------------------------

Added: trunk/src/main/org/jboss/jms/client/container/ClientConsumer.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/ClientConsumer.java	                        (rev 0)
+++ trunk/src/main/org/jboss/jms/client/container/ClientConsumer.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,921 @@
+/*
+  * 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.client.container;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jms.IllegalStateException;
+import javax.jms.JMSException;
+import javax.jms.MessageListener;
+import javax.jms.Session;
+
+import org.jboss.jms.delegate.ConsumerDelegate;
+import org.jboss.jms.delegate.SessionDelegate;
+import org.jboss.jms.message.MessageProxy;
+import org.jboss.jms.delegate.Cancel;
+import org.jboss.jms.delegate.DefaultCancel;
+import org.jboss.jms.delegate.DeliveryInfo;
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.util.Future;
+import org.jboss.messaging.util.prioritylinkedlist.BasicPriorityLinkedList;
+import org.jboss.messaging.util.prioritylinkedlist.PriorityLinkedList;
+
+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: 2774 $</tt>
+ *
+ * $Id: MessageCallbackHandler.java 2774 2007-06-12 22:43:54Z timfox $
+ */
+public class ClientConsumer
+{
+   // Constants ------------------------------------------------------------------------------------
+   
+   private static final Logger log;
+   
+   // Static ---------------------------------------------------------------------------------------
+   
+   private static boolean trace;      
+   
+   private static final int WAIT_TIMEOUT = 30000;
+   
+   
+   static
+   {
+      log = Logger.getLogger(ClientConsumer.class);
+      trace = log.isTraceEnabled();
+   }
+   
+   private static boolean checkExpiredOrReachedMaxdeliveries(MessageProxy proxy,
+                                                             SessionDelegate del,
+                                                             int maxDeliveries, boolean shouldCancel)
+   {
+      Message msg = proxy.getMessage();
+      
+      boolean expired = msg.isExpired();
+      
+      boolean reachedMaxDeliveries = proxy.getDeliveryCount() == maxDeliveries;
+      
+      if (expired || reachedMaxDeliveries)
+      {
+         if (trace)
+         {
+            if (expired)
+            {
+               log.trace(proxy.getMessage() + " has expired, cancelling to server");
+            }
+            else
+            {
+               log.trace(proxy.getMessage() + " has reached maximum delivery number, cancelling to server");
+            }
+         }
+         
+         if (shouldCancel)
+         {	         
+	         final Cancel cancel = new DefaultCancel(proxy.getDeliveryId(), proxy.getDeliveryCount(),
+	                                                 expired, reachedMaxDeliveries);	         
+	         try
+	         {
+	            del.cancelDelivery(cancel);
+	         }
+	         catch (JMSException e)
+	         {
+	            log.error("Failed to cancel delivery", e);
+	         }   
+         }
+               
+         return true;
+      }
+      else
+      {
+         return false;
+      }
+   }
+        
+   //This is static so it can be called by the asf layer too
+   public static void callOnMessage(SessionDelegate sess,
+                                    MessageListener listener,
+                                    int consumerID,
+                                    String queueName,
+                                    boolean isConnectionConsumer,
+                                    MessageProxy m,
+                                    int ackMode,
+                                    int maxDeliveries,
+                                    SessionDelegate connectionConsumerSession,
+                                    boolean shouldAck)
+      throws JMSException
+   {      
+      if (checkExpiredOrReachedMaxdeliveries(m, sess, maxDeliveries, shouldAck))
+      {
+         //Message has been cancelled
+         return;
+      }
+      
+      DeliveryInfo deliveryInfo =
+         new DeliveryInfo(m, consumerID, queueName, connectionConsumerSession, shouldAck);
+            
+      m.incDeliveryCount();
+      
+      // If this is the callback-handler for a connection consumer we don't want to acknowledge or
+      // add anything to the tx for this session.
+      if (!isConnectionConsumer)
+      {
+         //We need to call preDeliver, deliver the message then call postDeliver - this is because
+         //it is legal to call session.recover(), or session.rollback() from within the onMessage()
+         //method in which case the last message needs to be delivered so it needs to know about it
+         sess.preDeliver(deliveryInfo);
+      } 
+      
+      try
+      {
+         if (trace) { log.trace("calling listener's onMessage(" + m + ")"); }
+                     
+         listener.onMessage(m);
+
+         if (trace) { log.trace("listener's onMessage() finished"); }
+      }
+      catch (RuntimeException e)
+      {
+         long id = m.getMessage().getMessageID();
+
+         log.error("RuntimeException was thrown from onMessage, " + id + " will be redelivered", e);
+         
+         // See JMS 1.1 spec 4.5.2
+
+         if (ackMode == Session.AUTO_ACKNOWLEDGE || ackMode == Session.DUPS_OK_ACKNOWLEDGE)
+         {              
+            sess.recover();
+         }
+      }   
+
+      // If this is the callback-handler for a connection consumer we don't want to acknowledge
+      // or add anything to the tx for this session
+      if (!isConnectionConsumer)
+      {
+         sess.postDeliver();
+      }   
+   }
+   
+   // Attributes -----------------------------------------------------------------------------------
+      
+   /*
+    * The buffer is now a priority linked list
+    * This resolves problems whereby messages are delivered from the server side queue in
+    * correct priority order, but because the old consumer list was not a priority list
+    * then if messages were sitting waiting to be consumed on the client side, then higher
+    * priority messages might be behind lower priority messages and thus get consumed out of order
+    */
+   private PriorityLinkedList buffer;
+   private SessionDelegate sessionDelegate;
+   private ConsumerDelegate consumerDelegate;
+   private int consumerID;
+   private boolean isConnectionConsumer;
+   private volatile Thread receiverThread;
+   private MessageListener listener;
+   private int ackMode;
+   private boolean closed;
+   private Object mainLock;
+   private int maxBufferSize;
+   private int minBufferSize;
+   private QueuedExecutor sessionExecutor;
+   private boolean listenerRunning;
+   private int maxDeliveries;
+   private String queueName;
+   private long lastDeliveryId = -1;
+   private volatile boolean serverSending = true;
+   private boolean waitingForLastDelivery;
+   private boolean shouldAck;
+   private boolean handleFlowControl;
+        
+   
+   // Constructors ---------------------------------------------------------------------------------
+
+   public ClientConsumer(boolean isCC, int ackMode,                                
+                         SessionDelegate sess, ConsumerDelegate cons, int consumerID,
+                         String queueName,
+                         int bufferSize, QueuedExecutor sessionExecutor,
+                         int maxDeliveries, boolean shouldAck, boolean handleFlowControl)
+   {
+      if (bufferSize < 1)
+      {
+         throw new IllegalArgumentException(this + " bufferSize must be > 0");
+      }
+              
+      this.maxBufferSize = bufferSize;
+      this.minBufferSize = bufferSize / 2;
+      buffer = new BasicPriorityLinkedList(10);
+      isConnectionConsumer = isCC;
+      this.ackMode = ackMode;
+      this.sessionDelegate = sess;
+      this.consumerDelegate = cons;
+      this.consumerID = consumerID;
+      this.queueName = queueName;
+      mainLock = new Object();
+      this.sessionExecutor = sessionExecutor;
+      this.maxDeliveries = maxDeliveries;
+      this.shouldAck = shouldAck;
+      this.handleFlowControl = handleFlowControl;
+   }
+        
+   // Public ---------------------------------------------------------------------------------------
+
+   /**
+    * Handles a message sent from the server.
+    *
+    * @param message The message
+    */
+   public void handleMessage(final Object message) throws Exception
+   {
+      //TODO - we temporarily need to execute on a different thread to avoid a deadlock situation in
+      //       failover where a message is sent then the valve is locked, and the message send cause
+      //       a message delivery back to the same client which tries to ack but can't get through
+      //       the valve. This won't be necessary when we move to a non blocking transport
+      this.sessionExecutor.execute(
+         new Runnable()
+         {
+            public void run()
+            {
+               try
+               {
+                  handleMessageInternal(message);
+               }
+               catch (Exception e)
+               {
+                  log.error("Failed to handle message", e);
+               }
+            }
+         });
+   }
+   
+   public void setMessageListener(MessageListener listener) throws JMSException
+   {     
+      synchronized (mainLock)
+      {
+         if (receiverThread != null)
+         {
+            // Should never happen
+            throw new IllegalStateException("Consumer is currently in receive(..). " +
+               "Cannot set MessageListener");
+         }
+         
+         this.listener = listener;
+                            
+         if (listener != null && !buffer.isEmpty())
+         {  
+            listenerRunning = true;
+            
+            this.queueRunner(new ListenerRunner());
+         }        
+      }   
+   }
+   
+   public void cancelBuffer() throws JMSException
+   {
+      synchronized (mainLock)
+      {      
+         // Now we cancel anything left in the buffer. The reason we do this now is that otherwise
+         // the deliveries wouldn't get cancelled until session close (since we don't cancel
+         // consumer's deliveries until then), which is too late - since we need to preserve the
+         // order of messages delivered in a session.
+         
+         if (shouldAck && !buffer.isEmpty())
+         {                        
+            // Now we cancel any deliveries that might be waiting in our buffer. This is because
+            // otherwise the messages wouldn't get cancelled until the corresponding session died.
+            // So if another consumer in another session tried to consume from the channel before
+            // that session died it wouldn't receive those messages.
+            // We can't just cancel all the messages in the SCE since some of those messages might
+            // have actually been delivered (unlike these) and we may want to acknowledge them
+            // later, after this consumer has been closed
+   
+            List cancels = new ArrayList();
+   
+            for(Iterator i = buffer.iterator(); i.hasNext();)
+            {
+               MessageProxy mp = (MessageProxy)i.next();
+               
+               DefaultCancel cancel =
+                  new DefaultCancel(mp.getDeliveryId(), mp.getDeliveryCount(), false, false);
+               
+               cancels.add(cancel);
+            }
+                  
+            sessionDelegate.cancelDeliveries(cancels);
+            
+            buffer.clear();
+         }    
+      }
+   }
+   
+   public void close(long lastDeliveryId) throws JMSException
+   {     
+   	log.debug(this + " closing");
+         	
+   	//Wait for the last delivery to arrive
+      waitForLastDelivery(lastDeliveryId);
+      
+      //Important! We set the listener to null so the next ListenerRunner won't run
+      if (listener != null)
+      {
+      	setMessageListener(null);
+      }
+      
+      //Now we wait for any current listener runners to run.
+      waitForOnMessageToComplete();   
+      
+      synchronized (mainLock)
+      {         
+         if (closed)
+         {
+            return;
+         }
+         
+         closed = true;   
+         
+         if (receiverThread != null)
+         {            
+            // Wake up any receive() thread that might be waiting
+            mainLock.notify();
+         }   
+         
+         this.listener = null;
+      }
+                           
+      if (trace) { log.trace(this + " closed"); }
+   }
+     
+   /**
+    * Method used by the client thread to get a Message, if available.
+    *
+    * @param timeout - the timeout value in milliseconds. A zero timeount never expires, and the
+    *        call blocks indefinitely. A -1 timeout means receiveNoWait(): return the next message
+    *        or null if one is not immediately available. Returns null if the consumer is
+    *        concurrently closed.
+    */
+   public MessageProxy receive(long timeout) throws JMSException
+   {                
+      MessageProxy m = null;      
+      
+      synchronized (mainLock)
+      {        
+         if (trace) { log.trace(this + " receiving, timeout = " + timeout); }
+         
+         if (closed)
+         {
+            // If consumer is closed or closing calling receive returns null
+            if (trace) { log.trace(this + " closed, returning null"); }
+            return null;
+         }
+         
+         if (listener != null)
+         {
+            throw new JMSException("The consumer has a MessageListener set, " +
+               "cannot call receive(..)");
+         }
+                       
+         receiverThread = Thread.currentThread();
+               
+         long startTimestamp = System.currentTimeMillis();
+                  
+         try
+         {
+            while(true)
+            {                             
+               if (timeout == 0)
+               {
+                  if (trace) { log.trace(this + ": receive, no timeout"); }
+                  
+                  m = getMessage(0);                     
+                  
+                  if (m == null)
+                  {
+                     return null;
+                  }
+               }
+               else if (timeout == -1)
+               {
+                  //ReceiveNoWait
+                  if (trace) { log.trace(this + ": receive, noWait"); }
+                  
+                  m = getMessage(-1);                     
+                  
+                  if (m == null)
+                  {
+                     if (trace) { log.trace(this + ": no message available"); }
+                     return null;
+                  }
+               }
+               else
+               {
+                  if (trace) { log.trace(this + ": receive, timeout " + timeout + " ms, blocking poll on queue"); }
+                  
+                  m = getMessage(timeout);
+                                    
+                  if (m == null)
+                  {
+                     // timeout expired
+                     if (trace) { log.trace(this + ": " + timeout + " ms timeout expired"); }
+                     
+                     return null;
+                  }
+               }
+                              
+               if (trace) { log.trace(this + " received " + m + " after being blocked on buffer"); }
+                       
+               boolean ignore =
+                  checkExpiredOrReachedMaxdeliveries(m, sessionDelegate, maxDeliveries, shouldAck);
+               
+               if (!isConnectionConsumer && !ignore)
+               {
+                  DeliveryInfo info = new DeliveryInfo(m, consumerID, queueName, null, shouldAck);
+                                                    
+                  m.incDeliveryCount();           
+ 
+                  sessionDelegate.preDeliver(info);                  
+                  
+                  sessionDelegate.postDeliver();                                    
+               }
+                                             
+               if (!ignore)
+               {
+                  if (trace) { log.trace(this + ": message " + m + " is not expired, pushing it to the caller"); }
+                  
+                  break;
+               }
+               
+               if (trace)
+               {
+                  log.trace(this + ": message expired or exceeded max deliveries, discarding");
+               }
+               
+               // the message expired, so discard the message, adjust timeout and reenter the buffer
+               if (timeout != 0)
+               {
+                  timeout -= System.currentTimeMillis() - startTimestamp;
+               }                            
+            }           
+         }
+         finally
+         {
+            receiverThread = null;            
+         }
+      } 
+      
+      //This needs to be outside the lock
+
+      if (handleFlowControl)
+      {
+      	checkStart();
+      }
+      
+      if (trace) { log.trace(this + " receive() returning " + m); }
+      
+      return m;
+   } 
+         
+   public MessageListener getMessageListener()
+   {
+      return listener;      
+   }
+
+   public String toString()
+   {
+      return "ClientConsumer[" + consumerID + "]";
+   }
+   
+   public int getConsumerId()
+   {
+      return consumerID;
+   }
+
+   public void setConsumerId(int consumerId)
+   {
+       this.consumerID = consumerId;
+   }
+   
+   public void addToFrontOfBuffer(MessageProxy proxy) throws Exception
+   {
+      synchronized (mainLock)
+      {
+         buffer.addFirst(proxy, proxy.getJMSPriority());
+         
+         messageAdded();
+      }
+   }
+
+   /**
+    * Needed for failover
+    */
+   public void synchronizeWith(ClientConsumer newHandler)
+   {
+      consumerID = newHandler.consumerID;
+
+      // Clear the buffer. This way the non persistent messages that managed to arive are
+      // irremendiably lost, while the peristent ones are failed-over on the server and will be
+      // resent
+
+      // TODO If we don't zap this buffer, we may be able to salvage some non-persistent messages
+
+      buffer.clear();
+      
+      // need to reset toggle state
+      serverSending = true;      
+   }
+   
+   // Package protected ----------------------------------------------------------------------------
+   
+   // Protected ------------------------------------------------------------------------------------
+            
+   // Private --------------------------------------------------------------------------------------
+
+   /*
+    * Wait for the last delivery to arrive
+    */
+   private void waitForLastDelivery(long id)
+   {
+      if (trace) { log.trace("Waiting for last delivery id " + id); }
+      
+      synchronized (mainLock)
+      {          
+         waitingForLastDelivery = true;
+         try
+         {
+            long wait = WAIT_TIMEOUT;
+            while (lastDeliveryId != id && wait > 0)
+            {
+               long start = System.currentTimeMillis();  
+               try
+               {
+                  mainLock.wait(wait);
+               }
+               catch (InterruptedException e)
+               {               
+               }
+               wait -= (System.currentTimeMillis() - start);
+            }      
+            if (trace && lastDeliveryId == id)
+            {
+               log.trace("Got last delivery");
+            }
+             
+            if (lastDeliveryId != id)
+            {
+               log.warn("Timed out waiting for last delivery"); 
+            }
+         }
+         finally
+         {
+            waitingForLastDelivery = false;
+         }
+      }
+   }
+   
+   private void handleMessageInternal(Object message) throws Exception
+   {
+      MessageProxy proxy = (MessageProxy) message;
+
+      if (trace) { log.trace(this + " receiving message " + proxy + " from the remoting layer"); }
+
+      synchronized (mainLock)
+      {
+         if (closed)
+         {
+            // This should never happen - we should always wait for all deliveries to arrive
+            // when closing
+            log.warn(this + " is closed, so ignoring message");
+            
+            return;
+         }
+
+         proxy.setSessionDelegate(sessionDelegate, isConnectionConsumer);
+
+         //Add it to the buffer
+         buffer.addLast(proxy, proxy.getJMSPriority());
+
+         lastDeliveryId = proxy.getDeliveryId();
+         
+         if (trace) { log.trace(this + " added message(s) to the buffer"); }
+
+         messageAdded();
+
+         if (handleFlowControl)
+         {
+         	checkStop();
+         }
+      }
+   }
+
+   private void checkStop()
+   {
+      int size = buffer.size();
+      
+      if (serverSending && size >= maxBufferSize)
+      {
+         //Our buffer is full - we need to tell the server to stop sending if we haven't
+         //done so already
+         
+         sendChangeRateMessage(0f);
+         
+         if (trace) { log.trace("Sent changeRate 0 message"); }
+         
+         serverSending = false;
+      }
+   }
+   
+   private void checkStart()
+   {
+      int size = buffer.size();
+      
+      if (!serverSending && size <= minBufferSize)
+      {
+         //We need more messages - we need to tell the server this if we haven't done so already
+         
+         sendChangeRateMessage(1.0f);
+         
+         if (trace) { log.trace("Sent changeRate 1.0 message"); }
+         
+         serverSending = true;
+      }      
+   }
+   
+   private void sendChangeRateMessage(float newRate) 
+   {
+      try
+      {
+         // this invocation will be sent asynchronously to the server; it's DelegateSupport.invoke()
+         // job to detect it and turn it into a remoting one way invocation.
+         consumerDelegate.changeRate(newRate);
+      }
+      catch (JMSException e)
+      {
+         log.error("Failed to send changeRate message", e);
+      }
+   }
+   
+   private void waitForOnMessageToComplete()
+   {
+      // Wait for any onMessage() executions to complete
+
+      if (Thread.currentThread().equals(sessionExecutor.getThread()))
+      {
+         // the current thread already closing this ClientConsumer (this happens when the
+         // session is closed from within the MessageListener.onMessage(), for example), so no need
+         // to register another Closer (see http://jira.jboss.org/jira/browse/JBMESSAGING-542)
+         return;
+      }
+
+      Future result = new Future();
+      
+      try
+      {
+         sessionExecutor.execute(new Closer(result));
+
+         if (trace) { log.trace(this + " blocking wait for Closer execution"); }
+         result.getResult();
+         if (trace) { log.trace(this + " got Closer result"); }
+      }
+      catch (InterruptedException e)
+      {
+         log.warn("Thread interrupted", e);
+      }
+   }
+
+   private void queueRunner(ListenerRunner runner)
+   {
+      try
+      {
+         this.sessionExecutor.execute(runner);
+      }
+      catch (InterruptedException e)
+      {
+         log.warn("Thread interrupted", e);
+      }
+   }
+   
+   private void messageAdded()
+   {
+      boolean notified = false;
+      
+      // If we have a thread waiting on receive() we notify it
+      if (receiverThread != null)
+      {
+         if (trace) { log.trace(this + " notifying receiver/waiter thread"); }   
+         
+         mainLock.notifyAll();
+         
+         notified = true;
+      }     
+      else if (listener != null)
+      { 
+         // We have a message listener
+         if (!listenerRunning)
+         {
+            listenerRunning = true;
+
+            if (trace) { log.trace(this + " scheduled a new ListenerRunner"); }
+            this.queueRunner(new ListenerRunner());
+         }     
+         
+         //TODO - Execute onMessage on same thread for even better throughput 
+      }
+      
+      // Make sure we notify any thread waiting for last delivery
+      if (waitingForLastDelivery && !notified)
+      {
+         mainLock.notifyAll();
+      }
+   }
+   
+   private long waitOnLock(Object lock, long waitTime) throws InterruptedException
+   {
+      long start = System.currentTimeMillis();
+      
+      // Wait for last message to arrive
+      lock.wait(waitTime);
+     
+      long waited = System.currentTimeMillis() - start;
+      
+      if (waited < waitTime)
+      {
+         waitTime = waitTime - waited;
+         
+         return waitTime;
+      }
+      else
+      {
+         return 0;
+      }     
+   }
+        
+   private MessageProxy getMessage(long timeout)
+   {
+      if (timeout == -1)
+      {
+         // receiveNoWait so don't wait
+      }
+      else
+      {         
+         try
+         {         
+            if (timeout == 0)
+            {
+               // wait for ever potentially
+               while (!closed && buffer.isEmpty())
+               {
+                  if (trace) { log.trace(this + " waiting on main lock, no timeout"); }
+
+                  mainLock.wait();
+
+                  if (trace) { log.trace(this + " done waiting on main lock"); }
+               }
+            }
+            else
+            {
+               // wait with timeout
+               long toWait = timeout;
+             
+               while (!closed && buffer.isEmpty() && toWait > 0)
+               {
+                  if (trace) { log.trace(this + " waiting on main lock, timeout " + toWait + " ms"); }
+
+                  toWait = waitOnLock(mainLock, toWait);
+
+                  if (trace) { log.trace(this + " done waiting on lock, buffer is " + (buffer.isEmpty() ? "" : "NOT ") + "empty"); }
+               }
+            }
+         }
+         catch (InterruptedException e)
+         {
+            if (trace) { log.trace("InterruptedException, " + this + ".getMessage() returning null"); }
+            return null;
+         } 
+      }
+
+      MessageProxy m = null;
+             
+      if (!closed && !buffer.isEmpty())
+      {
+         m = (MessageProxy)buffer.removeFirst();
+      }
+
+      return m;
+   }
+   
+   // Inner classes --------------------------------------------------------------------------------
+         
+   /*
+    * This class is used to put on the listener executor to wait for onMessage
+    * invocations to complete when closing
+    */
+   private class Closer implements Runnable
+   {
+      Future result;
+      
+      Closer(Future result)
+      {
+         this.result = result;
+      }
+      
+      public void run()
+      {
+         if (trace) { log.trace("Closer starts running"); }
+
+         result.setResult(null);
+
+         if (trace) { log.trace("Closer finished run"); }
+      }
+   }
+   
+   /*
+    * This class handles the execution of onMessage methods
+    */
+   private class ListenerRunner implements Runnable
+   {
+      public void run()
+      {         
+         MessageProxy mp = null;
+         
+         MessageListener theListener = null;
+         
+         synchronized (mainLock)
+         {
+            if (listener == null || buffer.isEmpty())
+            {
+               listenerRunning = false;
+               
+               if (trace) { log.trace("no listener or buffer is empty, returning"); }
+               
+               return;
+            }
+            
+            theListener = listener;
+            
+            // remove a message from the buffer
+
+            mp = (MessageProxy)buffer.removeFirst();
+                          
+            if (!buffer.isEmpty())
+            {
+            	//Queue up the next runner to run
+            	
+            	if (trace) { log.trace("More messages in buffer so queueing next onMessage to run"); }
+            	
+            	queueRunner(this);
+            	
+            	if (trace) { log.trace("Queued next onMessage to run"); }
+            }
+            else
+            {
+            	if (trace) { log.trace("no more messages in buffer, marking listener as not running"); }
+            	
+            	listenerRunning  = false;
+            }               
+         }
+                        
+         if (mp != null)
+         {
+            try
+            {
+               callOnMessage(sessionDelegate, theListener, consumerID, queueName,
+                             false, mp, ackMode, maxDeliveries, null, shouldAck);
+            }
+            catch (JMSException e)
+            {
+               log.error("Failed to deliver message", e);
+            } 
+         }
+                  
+         if (handleFlowControl)
+         {
+         	checkStart();                                                   
+         }
+      }
+   }   
+}
+
+
+

Modified: trunk/src/main/org/jboss/jms/client/container/ClusteringAspect.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/ClusteringAspect.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/client/container/ClusteringAspect.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -127,9 +127,10 @@
 
             log.trace(this + " has chosen " + delegate + " as target, " +
                (attemptCount == 0 ? "first connection attempt" : attemptCount + " connection attempts"));
-
+  
             CreateConnectionResult res = delegate.
                createConnectionDelegate(username, password, failedNodeIDToServer);
+            
             ClientConnectionDelegate cd = (ClientConnectionDelegate)res.getDelegate();
 
             if (cd != null)

Modified: trunk/src/main/org/jboss/jms/client/container/ConsumerAspect.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/ConsumerAspect.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/client/container/ConsumerAspect.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -27,7 +27,6 @@
 import org.jboss.aop.joinpoint.MethodInvocation;
 import org.jboss.jms.client.delegate.DelegateSupport;
 import org.jboss.jms.client.remoting.CallbackManager;
-import org.jboss.jms.client.remoting.MessageCallbackHandler;
 import org.jboss.jms.client.state.ConnectionState;
 import org.jboss.jms.client.state.ConsumerState;
 import org.jboss.jms.client.state.SessionState;
@@ -99,21 +98,27 @@
          queueName = consumerState.getDestination().getName();
       }
       
-      MessageCallbackHandler messageHandler =
-         new MessageCallbackHandler(isCC, sessionState.getAcknowledgeMode(),
-                                    sessionDelegate, consumerDelegate, consumerID, queueName,
-                                    prefetchSize, sessionExecutor, maxDeliveries);
+      boolean autoFlowControl = ((Boolean)mi.getArguments()[5]).booleanValue();
       
+      ClientConsumer messageHandler =
+         new ClientConsumer(isCC, sessionState.getAcknowledgeMode(),
+                            sessionDelegate, consumerDelegate, consumerID, queueName,
+                            prefetchSize, sessionExecutor, maxDeliveries, consumerState.isShouldAck(),
+                            autoFlowControl);
+      
       sessionState.addCallbackHandler(messageHandler);
       
       CallbackManager cm = connectionState.getRemotingConnection().getCallbackManager();
       cm.registerHandler(consumerID, messageHandler);
          
-      consumerState.setMessageCallbackHandler(messageHandler);
+      consumerState.setClientConsumer(messageHandler);
       
-      //Now we have finished creating the client consumer, we can tell the SCD
-      //we are ready
-      consumerDelegate.changeRate(1);
+      if (autoFlowControl)
+      {
+	      //Now we have finished creating the client consumer, we can tell the SCD
+	      //we are ready
+	      consumerDelegate.changeRate(1);
+      }
 
       return consumerDelegate;
    }
@@ -129,20 +134,20 @@
       
       long lastDeliveryId = l.longValue();
       
-      // First we call close on the messagecallbackhandler which waits for onMessage invocations      
+      // First we call close on the ClientConsumer which waits for onMessage invocations      
       // to complete and the last delivery to arrive
-      consumerState.getMessageCallbackHandler().close(lastDeliveryId);
+      consumerState.getClientConsumer().close(lastDeliveryId);
                 
       SessionState sessionState = (SessionState)consumerState.getParent();
       ConnectionState connectionState = (ConnectionState)sessionState.getParent();
                  
-      sessionState.removeCallbackHandler(consumerState.getMessageCallbackHandler());
+      sessionState.removeCallbackHandler(consumerState.getClientConsumer());
 
       CallbackManager cm = connectionState.getRemotingConnection().getCallbackManager();
       cm.unregisterHandler(consumerState.getConsumerID());
          
       //And then we cancel any messages still in the message callback handler buffer     
-      consumerState.getMessageCallbackHandler().cancelBuffer();
+      consumerState.getClientConsumer().cancelBuffer();
                                    
       return l;
    }      
@@ -153,12 +158,12 @@
       Object[] args = mi.getArguments();
       long timeout = (args == null || args.length==0) ? 0 : ((Long)args[0]).longValue();
       
-      return getMessageCallbackHandler(invocation).receive(timeout);
+      return getClientConsumer(invocation).receive(timeout);
    }
    
    public Object handleReceiveNoWait(Invocation invocation) throws Throwable
    {      
-      return getMessageCallbackHandler(invocation).receive(-1);
+      return getClientConsumer(invocation).receive(-1);
    }
    
    public Object handleSetMessageListener(Invocation invocation) throws Throwable
@@ -167,14 +172,14 @@
       Object[] args = mi.getArguments();
       MessageListener l = (MessageListener)args[0];
       
-      getMessageCallbackHandler(invocation).setMessageListener(l);
+      getClientConsumer(invocation).setMessageListener(l);
       
       return null;
    }
    
    public MessageListener handleGetMessageListener(Invocation invocation) throws Throwable
    {       
-      return getMessageCallbackHandler(invocation).getMessageListener();
+      return getClientConsumer(invocation).getMessageListener();
    }
    
    public Object handleGetDestination(Invocation invocation) throws Throwable
@@ -203,10 +208,10 @@
       return (ConsumerState)((DelegateSupport)inv.getTargetObject()).getState();
    }
    
-   private MessageCallbackHandler getMessageCallbackHandler(Invocation inv)
+   private ClientConsumer getClientConsumer(Invocation inv)
    {      
       ConsumerState state = (ConsumerState)((DelegateSupport)inv.getTargetObject()).getState();
-      return state.getMessageCallbackHandler();      
+      return state.getClientConsumer();      
    }
    
    // Inner classes --------------------------------------------------------------------------------

Modified: trunk/src/main/org/jboss/jms/client/container/SessionAspect.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/SessionAspect.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/client/container/SessionAspect.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -39,7 +39,6 @@
 import org.jboss.jms.client.JBossConnectionConsumer;
 import org.jboss.jms.client.delegate.ClientSessionDelegate;
 import org.jboss.jms.client.delegate.DelegateSupport;
-import org.jboss.jms.client.remoting.MessageCallbackHandler;
 import org.jboss.jms.client.state.ConnectionState;
 import org.jboss.jms.client.state.SessionState;
 import org.jboss.jms.delegate.ConnectionDelegate;
@@ -159,7 +158,7 @@
          {               
             try
             {
-               del.acknowledgeDeliveries(state.getClientAckList());
+               acknowledgeDeliveries(del, state.getClientAckList());
             }
             finally
             {            
@@ -196,8 +195,7 @@
          
          cancelDeliveries(del, dels);        
       }
-            
-      
+                  
       return invocation.invokeNext();
    }      
    
@@ -305,15 +303,13 @@
       SessionState state = getState(invocation);
       
       int ackMode = state.getAcknowledgeMode();
+      
+      SessionDelegate sd = (SessionDelegate)mi.getTargetObject();
 
       // if XA and there is no transaction enlisted on XA we will act as AutoAcknowledge
       // However if it's a MDB (if there is a DistinguishedListener) we should behaved as transacted
       if (ackMode == Session.AUTO_ACKNOWLEDGE || isXAAndConsideredNonTransacted(state))
       {
-         // We auto acknowledge.
-
-         SessionDelegate sd = (SessionDelegate)mi.getTargetObject();
-
          // It is possible that session.recover() is called inside a message listener onMessage
          // method - i.e. between the invocations of preDeliver and postDeliver. In this case we
          // don't want to acknowledge the last delivered messages - since it will be redelivered.
@@ -328,7 +324,6 @@
                                  
             if (trace) { log.trace(this + " auto acknowledging delivery " + delivery); }
               
-
             // We clear the state in a finally so then we don't get a knock on
             // exception on the next ack since we haven't cleared the state. See
             // http://jira.jboss.org/jira/browse/JBMESSAGING-852
@@ -362,12 +357,10 @@
             {
                // We clear the state in a finally
                // http://jira.jboss.org/jira/browse/JBMESSAGING-852
-   
-               SessionDelegate sd = (SessionDelegate)mi.getTargetObject();
-                                          
+         
                try
                {
-                  sd.acknowledgeDeliveries(acks);
+                  acknowledgeDeliveries(sd, acks);
                }
                finally
                {                  
@@ -402,7 +395,7 @@
       {                 
          //CLIENT_ACKNOWLEDGE can't be used with a MDB so it is safe to always acknowledge all
          //on this session (rather than the connection consumer session)
-         del.acknowledgeDeliveries(state.getClientAckList());
+         acknowledgeDeliveries(del, state.getClientAckList());
       
          state.getClientAckList().clear();
       }      
@@ -516,7 +509,7 @@
          DeliveryInfo info = (DeliveryInfo)toRedeliver.get(i);
          MessageProxy proxy = info.getMessageProxy();        
          
-         MessageCallbackHandler handler = state.getCallbackHandler(info.getConsumerId());
+         ClientConsumer handler = state.getCallbackHandler(info.getConsumerId());
               
          if (handler == null)
          {
@@ -703,10 +696,8 @@
       }
       
       return new TextMessageProxy(jbm);
-   }   
-   
-   
-   
+   }      
+      
    public Object handleSetMessageListener(Invocation invocation) throws Throwable
    {
       if (trace) { log.trace("setMessageListener()"); }
@@ -762,6 +753,7 @@
       String queueName = (String)mi.getArguments()[2];
       int maxDeliveries = ((Integer)mi.getArguments()[3]).intValue();
       SessionDelegate connectionConsumerDelegate = ((SessionDelegate)mi.getArguments()[4]);
+      boolean shouldAck = ((Boolean)mi.getArguments()[5]).booleanValue();
       
       if (m == null)
       {
@@ -774,6 +766,7 @@
       holder.queueName = queueName;
       holder.maxDeliveries = maxDeliveries;
       holder.connectionConsumerDelegate = connectionConsumerDelegate;
+      holder.shouldAck = shouldAck;
       
       getState(invocation).getASFMessages().add(holder);
       
@@ -801,10 +794,10 @@
 
          if (trace) { log.trace("sending " + holder.msg + " to the message listener" ); }
          
-         MessageCallbackHandler.callOnMessage(del, state.getDistinguishedListener(), holder.consumerID,
+         ClientConsumer.callOnMessage(del, state.getDistinguishedListener(), holder.consumerID,
                                               holder.queueName, false,
                                               holder.msg, ackMode, holder.maxDeliveries,
-                                              holder.connectionConsumerDelegate);                          
+                                              holder.connectionConsumerDelegate, holder.shouldAck);                          
       }
       
       return null;
@@ -834,27 +827,33 @@
    
    private void ackDelivery(SessionDelegate sess, DeliveryInfo delivery) throws Exception
    {
-      SessionDelegate connectionConsumerSession = delivery.getConnectionConsumerSession();
-      
-      //If the delivery was obtained via a connection consumer we need to ack via that
-      //otherwise we just use this session
-      
-      SessionDelegate sessionToUse = connectionConsumerSession != null ? connectionConsumerSession : sess;
-      
-      sessionToUse.acknowledgeDelivery(delivery);      
+   	if (delivery.isShouldAck())
+   	{
+	      SessionDelegate connectionConsumerSession = delivery.getConnectionConsumerSession();
+	      
+	      //If the delivery was obtained via a connection consumer we need to ack via that
+	      //otherwise we just use this session
+	      
+	      SessionDelegate sessionToUse = connectionConsumerSession != null ? connectionConsumerSession : sess;
+	      
+	      sessionToUse.acknowledgeDelivery(delivery);
+   	}
    }
    
    private void cancelDelivery(SessionDelegate sess, DeliveryInfo delivery) throws Exception
    {
-      SessionDelegate connectionConsumerSession = delivery.getConnectionConsumerSession();
-      
-      //If the delivery was obtained via a connection consumer we need to cancel via that
-      //otherwise we just use this session
-      
-      SessionDelegate sessionToUse = connectionConsumerSession != null ? connectionConsumerSession : sess;
-      
-      sessionToUse.cancelDelivery(new DefaultCancel(delivery.getDeliveryID(),
-                                  delivery.getMessageProxy().getDeliveryCount(), false, false));      
+   	if (delivery.isShouldAck())
+   	{
+	      SessionDelegate connectionConsumerSession = delivery.getConnectionConsumerSession();
+	      
+	      //If the delivery was obtained via a connection consumer we need to cancel via that
+	      //otherwise we just use this session
+	      
+	      SessionDelegate sessionToUse = connectionConsumerSession != null ? connectionConsumerSession : sess;
+	      
+	      sessionToUse.cancelDelivery(new DefaultCancel(delivery.getDeliveryID(),
+	                                  delivery.getMessageProxy().getDeliveryCount(), false, false));      
+   	}
    }
    
    private void cancelDeliveries(SessionDelegate del, List deliveryInfos) throws Exception
@@ -863,13 +862,16 @@
       
       for (Iterator i = deliveryInfos.iterator(); i.hasNext(); )
       {
-         DeliveryInfo ack = (DeliveryInfo)i.next();            
+         DeliveryInfo ack = (DeliveryInfo)i.next();      
          
-         DefaultCancel cancel = new DefaultCancel(ack.getMessageProxy().getDeliveryId(),
-                                                  ack.getMessageProxy().getDeliveryCount(),
-                                                  false, false);
-         
-         cancels.add(cancel);
+         if (ack.isShouldAck())
+         {         
+	         DefaultCancel cancel = new DefaultCancel(ack.getMessageProxy().getDeliveryId(),
+	                                                  ack.getMessageProxy().getDeliveryCount(),
+	                                                  false, false);
+	         
+	         cancels.add(cancel);
+         }
       }  
       
       if (!cancels.isEmpty())
@@ -877,6 +879,26 @@
          del.cancelDeliveries(cancels);
       }
    }
+   
+   private void acknowledgeDeliveries(SessionDelegate del, List deliveryInfos) throws Exception
+   {
+      List acks = new ArrayList();
+      
+      for (Iterator i = deliveryInfos.iterator(); i.hasNext(); )
+      {
+         DeliveryInfo ack = (DeliveryInfo)i.next();      
+         
+         if (ack.isShouldAck())
+         {         
+	         acks.add(ack);
+         }
+      }  
+      
+      if (!acks.isEmpty())
+      {
+         del.acknowledgeDeliveries(acks);
+      }
+   }
 
    /** http://jira.jboss.org/jira/browse/JBMESSAGING-946 - To accomodate TCK and the MQ behavior
     *    we should behave as non transacted, AUTO_ACK when there is no transaction enlisted
@@ -898,6 +920,7 @@
       private String queueName;
       private int maxDeliveries;
       private SessionDelegate connectionConsumerDelegate;
+      private boolean shouldAck;
    }
    
 }

Modified: trunk/src/main/org/jboss/jms/client/container/StateCreationAspect.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/StateCreationAspect.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/client/container/StateCreationAspect.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -116,6 +116,7 @@
                                 remotingConnection, versionToUse, idGenerator);
 
          listener.setConnectionState(connectionState);
+          
          connectionDelegate.setState(connectionState);
       }
 

Modified: trunk/src/main/org/jboss/jms/client/delegate/ClientClusteredConnectionFactoryDelegate.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/delegate/ClientClusteredConnectionFactoryDelegate.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/client/delegate/ClientClusteredConnectionFactoryDelegate.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -173,7 +173,7 @@
    /** Method used to update the delegate and failoverMap during viewChange */
    public synchronized void updateFailoverInfo(ClientConnectionFactoryDelegate[] delegates,
                                                Map failoverMap)
-   {
+   {	
       this.delegates = delegates;
       this.failoverMap = failoverMap;
 

Modified: trunk/src/main/org/jboss/jms/client/delegate/ClientSessionDelegate.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/delegate/ClientSessionDelegate.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/client/delegate/ClientSessionDelegate.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -222,10 +222,11 @@
 
    public ConsumerDelegate createConsumerDelegate(JBossDestination destination, String selector,
                                                   boolean noLocal, String subscriptionName,
-                                                  boolean connectionConsumer) throws JMSException
+                                                  boolean connectionConsumer, boolean started) throws JMSException
    {
       RequestSupport req = new SessionCreateConsumerDelegateRequest(id, version, destination,
-                                                                    selector, noLocal, subscriptionName, connectionConsumer);
+                                                                    selector, noLocal, subscriptionName,
+                                                                    connectionConsumer, started);
 
       return (ConsumerDelegate)doInvoke(client, req);
    }
@@ -434,7 +435,7 @@
     * server-side endpoint.
     */
    public void addAsfMessage(MessageProxy m, int consumerID, String queueName, int maxDeliveries,
-                             SessionDelegate connectionConsumerSession)
+                             SessionDelegate connectionConsumerSession, boolean shouldAck)
    {
       throw new IllegalStateException("This invocation should not be handled here!");
    }

Modified: trunk/src/main/org/jboss/jms/client/remoting/CallbackManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/remoting/CallbackManager.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/client/remoting/CallbackManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,13 +23,14 @@
 
 import java.util.Map;
 
+import org.jboss.jms.client.container.ClientConsumer;
 import org.jboss.jms.client.delegate.ClientConnectionDelegate;
 import org.jboss.jms.message.JBossMessage;
 import org.jboss.jms.message.MessageProxy;
 import org.jboss.jms.wireformat.ClientDelivery;
 import org.jboss.jms.wireformat.ConnectionFactoryUpdate;
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.message.Message;
+import org.jboss.messaging.core.contract.Message;
 import org.jboss.remoting.callback.Callback;
 import org.jboss.remoting.callback.HandleCallbackException;
 import org.jboss.remoting.callback.InvokerCallbackHandler;
@@ -65,7 +66,7 @@
 
    // Attributes -----------------------------------------------------------------------------------
 
-   // Map<Long(lookup)-MessageCallbackHandler>
+   // Map<Long(lookup)-ClientConsumer>
    protected Map callbackHandlers;
    protected ConnectionFactoryCallbackHandler connectionfactoryCallbackHandler;
 
@@ -91,8 +92,8 @@
          MessageProxy proxy = JBossMessage.
             createThinDelegate(dr.getDeliveryId(), (JBossMessage)msg, dr.getDeliveryCount());
 
-         MessageCallbackHandler handler =
-            (MessageCallbackHandler)callbackHandlers.get(new Integer(dr.getConsumerId()));
+         ClientConsumer handler =
+            (ClientConsumer)callbackHandlers.get(new Integer(dr.getConsumerId()));
 
          if (handler == null)
          {
@@ -133,7 +134,7 @@
 
    // Public ---------------------------------------------------------------------------------------
 
-   public void registerHandler(int consumerID, MessageCallbackHandler handler)
+   public void registerHandler(int consumerID, ClientConsumer handler)
    {
       callbackHandlers.put(new Integer(consumerID), handler);
    }
@@ -144,9 +145,9 @@
          new ConnectionFactoryCallbackHandler(connectionDelegate);
    }
 
-   public MessageCallbackHandler unregisterHandler(int consumerID)
+   public ClientConsumer unregisterHandler(int consumerID)
    { 
-      return (MessageCallbackHandler)callbackHandlers.remove(new Integer(consumerID));
+      return (ClientConsumer)callbackHandlers.remove(new Integer(consumerID));
    }
 
    public String toString()

Deleted: trunk/src/main/org/jboss/jms/client/remoting/MessageCallbackHandler.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/remoting/MessageCallbackHandler.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/client/remoting/MessageCallbackHandler.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,904 +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.client.remoting;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.jms.IllegalStateException;
-import javax.jms.JMSException;
-import javax.jms.MessageListener;
-import javax.jms.Session;
-
-import org.jboss.jms.delegate.ConsumerDelegate;
-import org.jboss.jms.delegate.SessionDelegate;
-import org.jboss.jms.message.MessageProxy;
-import org.jboss.jms.delegate.Cancel;
-import org.jboss.jms.delegate.DefaultCancel;
-import org.jboss.jms.delegate.DeliveryInfo;
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.util.Future;
-import org.jboss.messaging.util.prioritylinkedlist.BasicPriorityLinkedList;
-import org.jboss.messaging.util.prioritylinkedlist.PriorityLinkedList;
-
-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 MessageCallbackHandler
-{
-   // Constants ------------------------------------------------------------------------------------
-   
-   private static final Logger log;
-   
-   // Static ---------------------------------------------------------------------------------------
-   
-   private static boolean trace;      
-   
-   private static final int WAIT_TIMEOUT = 30000;
-   
-   
-   static
-   {
-      log = Logger.getLogger(MessageCallbackHandler.class);
-      trace = log.isTraceEnabled();
-   }
-   
-   private static boolean checkExpiredOrReachedMaxdeliveries(MessageProxy proxy,
-                                                             SessionDelegate del,
-                                                             int maxDeliveries)
-   {
-      Message msg = proxy.getMessage();
-      
-      boolean expired = msg.isExpired();
-      
-      boolean reachedMaxDeliveries = proxy.getDeliveryCount() == maxDeliveries;
-      
-      if (expired || reachedMaxDeliveries)
-      {
-         if (trace)
-         {
-            if (expired)
-            {
-               log.trace(proxy.getMessage() + " has expired, cancelling to server");
-            }
-            else
-            {
-               log.trace(proxy.getMessage() + " has reached maximum delivery number, cancelling to server");
-            }
-         }
-         final Cancel cancel = new DefaultCancel(proxy.getDeliveryId(), proxy.getDeliveryCount(),
-                                                 expired, reachedMaxDeliveries);
-         
-         try
-         {
-            del.cancelDelivery(cancel);
-         }
-         catch (JMSException e)
-         {
-            log.error("Failed to cancel delivery", e);
-         }   
-               
-         return true;
-      }
-      else
-      {
-         return false;
-      }
-   }
-        
-   //This is static so it can be called by the asf layer too
-   public static void callOnMessage(SessionDelegate sess,
-                                    MessageListener listener,
-                                    int consumerID,
-                                    String queueName,
-                                    boolean isConnectionConsumer,
-                                    MessageProxy m,
-                                    int ackMode,
-                                    int maxDeliveries,
-                                    SessionDelegate connectionConsumerSession)
-      throws JMSException
-   {      
-      if (checkExpiredOrReachedMaxdeliveries(m, sess, maxDeliveries))
-      {
-         //Message has been cancelled
-         return;
-      }
-      
-      DeliveryInfo deliveryInfo =
-         new DeliveryInfo(m, consumerID, queueName, connectionConsumerSession);
-            
-      m.incDeliveryCount();
-      
-      // If this is the callback-handler for a connection consumer we don't want to acknowledge or
-      // add anything to the tx for this session.
-      if (!isConnectionConsumer)
-      {
-         //We need to call preDeliver, deliver the message then call postDeliver - this is because
-         //it is legal to call session.recover(), or session.rollback() from within the onMessage()
-         //method in which case the last message needs to be delivered so it needs to know about it
-         sess.preDeliver(deliveryInfo);
-      } 
-      
-      try
-      {
-         if (trace) { log.trace("calling listener's onMessage(" + m + ")"); }
-                     
-         listener.onMessage(m);
-
-         if (trace) { log.trace("listener's onMessage() finished"); }
-      }
-      catch (RuntimeException e)
-      {
-         long id = m.getMessage().getMessageID();
-
-         log.error("RuntimeException was thrown from onMessage, " + id + " will be redelivered", e);
-         
-         // See JMS 1.1 spec 4.5.2
-
-         if (ackMode == Session.AUTO_ACKNOWLEDGE || ackMode == Session.DUPS_OK_ACKNOWLEDGE)
-         {              
-            sess.recover();
-         }
-      }   
-
-      // If this is the callback-handler for a connection consumer we don't want to acknowledge
-      // or add anything to the tx for this session
-      if (!isConnectionConsumer)
-      {
-         sess.postDeliver();
-      }   
-   }
-   
-   // Attributes -----------------------------------------------------------------------------------
-      
-   /*
-    * The buffer is now a priority linked list
-    * This resolves problems whereby messages are delivered from the server side queue in
-    * correct priority order, but because the old consumer list was not a priority list
-    * then if messages were sitting waiting to be consumed on the client side, then higher
-    * priority messages might be behind lower priority messages and thus get consumed out of order
-    */
-   private PriorityLinkedList buffer;
-   private SessionDelegate sessionDelegate;
-   private ConsumerDelegate consumerDelegate;
-   private int consumerID;
-   private boolean isConnectionConsumer;
-   private volatile Thread receiverThread;
-   private MessageListener listener;
-   private int ackMode;
-   private boolean closed;
-   private Object mainLock;
-   private int maxBufferSize;
-   private int minBufferSize;
-   private QueuedExecutor sessionExecutor;
-   private boolean listenerRunning;
-   private int maxDeliveries;
-   private String queueName;
-   private long lastDeliveryId = -1;
-   private volatile boolean serverSending = true;
-   private boolean waitingForLastDelivery;
-        
-   
-   // Constructors ---------------------------------------------------------------------------------
-
-   public MessageCallbackHandler(boolean isCC, int ackMode,                                
-                                 SessionDelegate sess, ConsumerDelegate cons, int consumerID,
-                                 String queueName,
-                                 int bufferSize, QueuedExecutor sessionExecutor,
-                                 int maxDeliveries)
-   {
-      if (bufferSize < 1)
-      {
-         throw new IllegalArgumentException(this + " bufferSize must be > 0");
-      }
-              
-      this.maxBufferSize = bufferSize;
-      this.minBufferSize = bufferSize / 2;
-      buffer = new BasicPriorityLinkedList(10);
-      isConnectionConsumer = isCC;
-      this.ackMode = ackMode;
-      this.sessionDelegate = sess;
-      this.consumerDelegate = cons;
-      this.consumerID = consumerID;
-      this.queueName = queueName;
-      mainLock = new Object();
-      this.sessionExecutor = sessionExecutor;
-      this.maxDeliveries = maxDeliveries;
-   }
-        
-   // Public ---------------------------------------------------------------------------------------
-
-   /**
-    * Handles a message sent from the server.
-    *
-    * @param message The message
-    */
-   public void handleMessage(final Object message) throws Exception
-   {
-      //TODO - we temporarily need to execute on a different thread to avoid a deadlock situation in
-      //       failover where a message is sent then the valve is locked, and the message send cause
-      //       a message delivery back to the same client which tries to ack but can't get through
-      //       the valve. This won't be necessary when we move to a non blocking transport
-      this.sessionExecutor.execute(
-         new Runnable()
-         {
-            public void run()
-            {
-               try
-               {
-                  handleMessageInternal(message);
-               }
-               catch (Exception e)
-               {
-                  log.error("Failed to handle message", e);
-               }
-            }
-         });
-   }
-   
-   public void setMessageListener(MessageListener listener) throws JMSException
-   {     
-      synchronized (mainLock)
-      {
-         if (receiverThread != null)
-         {
-            // Should never happen
-            throw new IllegalStateException("Consumer is currently in receive(..). " +
-               "Cannot set MessageListener");
-         }
-         
-         this.listener = listener;
-                            
-         if (listener != null && !buffer.isEmpty())
-         {  
-            listenerRunning = true;
-            
-            this.queueRunner(new ListenerRunner());
-         }        
-      }   
-   }
-   
-   public void cancelBuffer() throws JMSException
-   {
-      synchronized (mainLock)
-      {      
-         // Now we cancel anything left in the buffer. The reason we do this now is that otherwise
-         // the deliveries wouldn't get cancelled until session close (since we don't cancel
-         // consumer's deliveries until then), which is too late - since we need to preserve the
-         // order of messages delivered in a session.
-         
-         if (!buffer.isEmpty())
-         {                        
-            // Now we cancel any deliveries that might be waiting in our buffer. This is because
-            // otherwise the messages wouldn't get cancelled until the corresponding session died.
-            // So if another consumer in another session tried to consume from the channel before
-            // that session died it wouldn't receive those messages.
-            // We can't just cancel all the messages in the SCE since some of those messages might
-            // have actually been delivered (unlike these) and we may want to acknowledge them
-            // later, after this consumer has been closed
-   
-            List cancels = new ArrayList();
-   
-            for(Iterator i = buffer.iterator(); i.hasNext();)
-            {
-               MessageProxy mp = (MessageProxy)i.next();
-               
-               DefaultCancel cancel =
-                  new DefaultCancel(mp.getDeliveryId(), mp.getDeliveryCount(), false, false);
-               
-               cancels.add(cancel);
-            }
-                  
-            sessionDelegate.cancelDeliveries(cancels);
-            
-            buffer.clear();
-         }    
-      }
-   }
-   
-   public void close(long lastDeliveryId) throws JMSException
-   {     
-   	log.debug(this + " closing");
-         	
-   	//Wait for the last delivery to arrive
-      waitForLastDelivery(lastDeliveryId);
-      
-      //Important! We set the listener to null so the next ListenerRunner won't run
-      if (listener != null)
-      {
-      	setMessageListener(null);
-      }
-      
-      //Now we wait for any current listener runners to run.
-      waitForOnMessageToComplete();   
-      
-      synchronized (mainLock)
-      {         
-         if (closed)
-         {
-            return;
-         }
-         
-         closed = true;   
-         
-         if (receiverThread != null)
-         {            
-            // Wake up any receive() thread that might be waiting
-            mainLock.notify();
-         }   
-         
-         this.listener = null;
-      }
-                           
-      if (trace) { log.trace(this + " closed"); }
-   }
-     
-   /**
-    * Method used by the client thread to get a Message, if available.
-    *
-    * @param timeout - the timeout value in milliseconds. A zero timeount never expires, and the
-    *        call blocks indefinitely. A -1 timeout means receiveNoWait(): return the next message
-    *        or null if one is not immediately available. Returns null if the consumer is
-    *        concurrently closed.
-    */
-   public MessageProxy receive(long timeout) throws JMSException
-   {                
-      MessageProxy m = null;      
-      
-      synchronized (mainLock)
-      {        
-         if (trace) { log.trace(this + " receiving, timeout = " + timeout); }
-         
-         if (closed)
-         {
-            // If consumer is closed or closing calling receive returns null
-            if (trace) { log.trace(this + " closed, returning null"); }
-            return null;
-         }
-         
-         if (listener != null)
-         {
-            throw new JMSException("The consumer has a MessageListener set, " +
-               "cannot call receive(..)");
-         }
-                       
-         receiverThread = Thread.currentThread();
-               
-         long startTimestamp = System.currentTimeMillis();
-                  
-         try
-         {
-            while(true)
-            {                             
-               if (timeout == 0)
-               {
-                  if (trace) { log.trace(this + ": receive, no timeout"); }
-                  
-                  m = getMessage(0);                     
-                  
-                  if (m == null)
-                  {
-                     return null;
-                  }
-               }
-               else if (timeout == -1)
-               {
-                  //ReceiveNoWait
-                  if (trace) { log.trace(this + ": receive, noWait"); }
-                  
-                  m = getMessage(-1);                     
-                  
-                  if (m == null)
-                  {
-                     if (trace) { log.trace(this + ": no message available"); }
-                     return null;
-                  }
-               }
-               else
-               {
-                  if (trace) { log.trace(this + ": receive, timeout " + timeout + " ms, blocking poll on queue"); }
-                  
-                  m = getMessage(timeout);
-                                    
-                  if (m == null)
-                  {
-                     // timeout expired
-                     if (trace) { log.trace(this + ": " + timeout + " ms timeout expired"); }
-                     
-                     return null;
-                  }
-               }
-                              
-               if (trace) { log.trace(this + " received " + m + " after being blocked on buffer"); }
-                       
-               boolean ignore =
-                  checkExpiredOrReachedMaxdeliveries(m, sessionDelegate, maxDeliveries);
-               
-               if (!isConnectionConsumer && !ignore)
-               {
-                  DeliveryInfo info = new DeliveryInfo(m, consumerID, queueName, null);
-                                                    
-                  m.incDeliveryCount();           
- 
-                  sessionDelegate.preDeliver(info);                  
-                  
-                  sessionDelegate.postDeliver();                                    
-               }
-                                             
-               if (!ignore)
-               {
-                  if (trace) { log.trace(this + ": message " + m + " is not expired, pushing it to the caller"); }
-                  
-                  break;
-               }
-               
-               if (trace)
-               {
-                  log.trace(this + ": message expired or exceeded max deliveries, discarding");
-               }
-               
-               // the message expired, so discard the message, adjust timeout and reenter the buffer
-               if (timeout != 0)
-               {
-                  timeout -= System.currentTimeMillis() - startTimestamp;
-               }                            
-            }           
-         }
-         finally
-         {
-            receiverThread = null;            
-         }
-      } 
-      
-      //This needs to be outside the lock
-
-      checkStart();
-      
-      if (trace) { log.trace(this + " receive() returning " + m); }
-      
-      return m;
-   } 
-         
-   public MessageListener getMessageListener()
-   {
-      return listener;      
-   }
-
-   public String toString()
-   {
-      return "MessageCallbackHandler[" + consumerID + "]";
-   }
-   
-   public int getConsumerId()
-   {
-      return consumerID;
-   }
-
-   public void setConsumerId(int consumerId)
-   {
-       this.consumerID = consumerId;
-   }
-   
-   public void addToFrontOfBuffer(MessageProxy proxy) throws Exception
-   {
-      synchronized (mainLock)
-      {
-         buffer.addFirst(proxy, proxy.getJMSPriority());
-         
-         messageAdded();
-      }
-   }
-
-   /**
-    * Needed for failover
-    */
-   public void synchronizeWith(MessageCallbackHandler newHandler)
-   {
-      consumerID = newHandler.consumerID;
-
-      // Clear the buffer. This way the non persistent messages that managed to arive are
-      // irremendiably lost, while the peristent ones are failed-over on the server and will be
-      // resent
-
-      // TODO If we don't zap this buffer, we may be able to salvage some non-persistent messages
-
-      buffer.clear();
-      
-      // need to reset toggle state
-      serverSending = true;      
-   }
-   
-   // Package protected ----------------------------------------------------------------------------
-   
-   // Protected ------------------------------------------------------------------------------------
-            
-   // Private --------------------------------------------------------------------------------------
-
-   /*
-    * Wait for the last delivery to arrive
-    */
-   private void waitForLastDelivery(long id)
-   {
-      if (trace) { log.trace("Waiting for last delivery id " + id); }
-      
-      synchronized (mainLock)
-      {          
-         waitingForLastDelivery = true;
-         try
-         {
-            long wait = WAIT_TIMEOUT;
-            while (lastDeliveryId != id && wait > 0)
-            {
-               long start = System.currentTimeMillis();  
-               try
-               {
-                  mainLock.wait(wait);
-               }
-               catch (InterruptedException e)
-               {               
-               }
-               wait -= (System.currentTimeMillis() - start);
-            }      
-            if (trace && lastDeliveryId == id)
-            {
-               log.trace("Got last delivery");
-            }
-             
-            if (lastDeliveryId != id)
-            {
-               log.warn("Timed out waiting for last delivery"); 
-            }
-         }
-         finally
-         {
-            waitingForLastDelivery = false;
-         }
-      }
-   }
-   
-   private void handleMessageInternal(Object message) throws Exception
-   {
-      MessageProxy proxy = (MessageProxy) message;
-
-      if (trace) { log.trace(this + " receiving message " + proxy + " from the remoting layer"); }
-
-      synchronized (mainLock)
-      {
-         if (closed)
-         {
-            // This should never happen - we should always wait for all deliveries to arrive
-            // when closing
-            log.warn(this + " is closed, so ignoring message");
-            
-            return;
-         }
-
-         proxy.setSessionDelegate(sessionDelegate, isConnectionConsumer);
-
-         //Add it to the buffer
-         buffer.addLast(proxy, proxy.getJMSPriority());
-
-         lastDeliveryId = proxy.getDeliveryId();
-         
-         if (trace) { log.trace(this + " added message(s) to the buffer"); }
-
-         messageAdded();
-
-         checkStop();
-      }
-   }
-
-   private void checkStop()
-   {
-      int size = buffer.size();
-      
-      if (serverSending && size >= maxBufferSize)
-      {
-         //Our buffer is full - we need to tell the server to stop sending if we haven't
-         //done so already
-         
-         sendChangeRateMessage(0f);
-         
-         if (trace) { log.trace("Sent changeRate 0 message"); }
-         
-         serverSending = false;
-      }
-   }
-   
-   private void checkStart()
-   {
-      int size = buffer.size();
-      
-      if (!serverSending && size <= minBufferSize)
-      {
-         //We need more messages - we need to tell the server this if we haven't done so already
-         
-         sendChangeRateMessage(1.0f);
-         
-         if (trace) { log.trace("Sent changeRate 1.0 message"); }
-         
-         serverSending = true;
-      }      
-   }
-   
-   private void sendChangeRateMessage(float newRate) 
-   {
-      try
-      {
-         // this invocation will be sent asynchronously to the server; it's DelegateSupport.invoke()
-         // job to detect it and turn it into a remoting one way invocation.
-         consumerDelegate.changeRate(newRate);
-      }
-      catch (JMSException e)
-      {
-         log.error("Failed to send changeRate message", e);
-      }
-   }
-   
-   private void waitForOnMessageToComplete()
-   {
-      // Wait for any onMessage() executions to complete
-
-      if (Thread.currentThread().equals(sessionExecutor.getThread()))
-      {
-         // the current thread already closing this MessageCallbackHandler (this happens when the
-         // session is closed from within the MessageListener.onMessage(), for example), so no need
-         // to register another Closer (see http://jira.jboss.org/jira/browse/JBMESSAGING-542)
-         return;
-      }
-
-      Future result = new Future();
-      
-      try
-      {
-         sessionExecutor.execute(new Closer(result));
-
-         if (trace) { log.trace(this + " blocking wait for Closer execution"); }
-         result.getResult();
-         if (trace) { log.trace(this + " got Closer result"); }
-      }
-      catch (InterruptedException e)
-      {
-         log.warn("Thread interrupted", e);
-      }
-   }
-
-   private void queueRunner(ListenerRunner runner)
-   {
-      try
-      {
-         this.sessionExecutor.execute(runner);
-      }
-      catch (InterruptedException e)
-      {
-         log.warn("Thread interrupted", e);
-      }
-   }
-   
-   private void messageAdded()
-   {
-      boolean notified = false;
-      
-      // If we have a thread waiting on receive() we notify it
-      if (receiverThread != null)
-      {
-         if (trace) { log.trace(this + " notifying receiver/waiter thread"); }   
-         
-         mainLock.notifyAll();
-         
-         notified = true;
-      }     
-      else if (listener != null)
-      { 
-         // We have a message listener
-         if (!listenerRunning)
-         {
-            listenerRunning = true;
-
-            if (trace) { log.trace(this + " scheduled a new ListenerRunner"); }
-            this.queueRunner(new ListenerRunner());
-         }     
-         
-         //TODO - Execute onMessage on same thread for even better throughput 
-      }
-      
-      // Make sure we notify any thread waiting for last delivery
-      if (waitingForLastDelivery && !notified)
-      {
-         mainLock.notifyAll();
-      }
-   }
-   
-   private long waitOnLock(Object lock, long waitTime) throws InterruptedException
-   {
-      long start = System.currentTimeMillis();
-      
-      // Wait for last message to arrive
-      lock.wait(waitTime);
-     
-      long waited = System.currentTimeMillis() - start;
-      
-      if (waited < waitTime)
-      {
-         waitTime = waitTime - waited;
-         
-         return waitTime;
-      }
-      else
-      {
-         return 0;
-      }     
-   }
-        
-   private MessageProxy getMessage(long timeout)
-   {
-      if (timeout == -1)
-      {
-         // receiveNoWait so don't wait
-      }
-      else
-      {         
-         try
-         {         
-            if (timeout == 0)
-            {
-               // wait for ever potentially
-               while (!closed && buffer.isEmpty())
-               {
-                  if (trace) { log.trace(this + " waiting on main lock, no timeout"); }
-
-                  mainLock.wait();
-
-                  if (trace) { log.trace(this + " done waiting on main lock"); }
-               }
-            }
-            else
-            {
-               // wait with timeout
-               long toWait = timeout;
-             
-               while (!closed && buffer.isEmpty() && toWait > 0)
-               {
-                  if (trace) { log.trace(this + " waiting on main lock, timeout " + toWait + " ms"); }
-
-                  toWait = waitOnLock(mainLock, toWait);
-
-                  if (trace) { log.trace(this + " done waiting on lock, buffer is " + (buffer.isEmpty() ? "" : "NOT ") + "empty"); }
-               }
-            }
-         }
-         catch (InterruptedException e)
-         {
-            if (trace) { log.trace("InterruptedException, " + this + ".getMessage() returning null"); }
-            return null;
-         } 
-      }
-
-      MessageProxy m = null;
-             
-      if (!closed && !buffer.isEmpty())
-      {
-         m = (MessageProxy)buffer.removeFirst();
-      }
-
-      return m;
-   }
-   
-   // Inner classes --------------------------------------------------------------------------------
-         
-   /*
-    * This class is used to put on the listener executor to wait for onMessage
-    * invocations to complete when closing
-    */
-   private class Closer implements Runnable
-   {
-      Future result;
-      
-      Closer(Future result)
-      {
-         this.result = result;
-      }
-      
-      public void run()
-      {
-         if (trace) { log.trace("Closer starts running"); }
-
-         result.setResult(null);
-
-         if (trace) { log.trace("Closer finished run"); }
-      }
-   }
-   
-   /*
-    * This class handles the execution of onMessage methods
-    */
-   private class ListenerRunner implements Runnable
-   {
-      public void run()
-      {         
-         MessageProxy mp = null;
-         
-         MessageListener theListener = null;
-         
-         synchronized (mainLock)
-         {
-            if (listener == null || buffer.isEmpty())
-            {
-               listenerRunning = false;
-               
-               if (trace) { log.trace("no listener or buffer is empty, returning"); }
-               
-               return;
-            }
-            
-            theListener = listener;
-            
-            // remove a message from the buffer
-
-            mp = (MessageProxy)buffer.removeFirst();
-                          
-            if (!buffer.isEmpty())
-            {
-            	//Queue up the next runner to run
-            	
-            	if (trace) { log.trace("More messages in buffer so queueing next onMessage to run"); }
-            	
-            	queueRunner(this);
-            	
-            	if (trace) { log.trace("Queued next onMessage to run"); }
-            }
-            else
-            {
-            	if (trace) { log.trace("no more messages in buffer, marking listener as not running"); }
-            	
-            	listenerRunning  = false;
-            }               
-         }
-                        
-         if (mp != null)
-         {
-            try
-            {
-               callOnMessage(sessionDelegate, theListener, consumerID, queueName,
-                             false, mp, ackMode, maxDeliveries, null);
-            }
-            catch (JMSException e)
-            {
-               log.error("Failed to deliver message", e);
-            } 
-         }
-                  
-         checkStart();                                                   
-      }
-   }   
-}
-
-
-

Modified: trunk/src/main/org/jboss/jms/client/state/ConsumerState.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/state/ConsumerState.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/client/state/ConsumerState.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,10 +23,10 @@
 
 import java.util.Collections;
 
+import org.jboss.jms.client.container.ClientConsumer;
 import org.jboss.jms.client.delegate.ClientConnectionDelegate;
 import org.jboss.jms.client.delegate.DelegateSupport;
 import org.jboss.jms.client.remoting.CallbackManager;
-import org.jboss.jms.client.remoting.MessageCallbackHandler;
 import org.jboss.jms.delegate.ConsumerDelegate;
 import org.jboss.jms.destination.JBossDestination;
 import org.jboss.messaging.util.Version;
@@ -56,7 +56,7 @@
    private String subscriptionName;
    private boolean noLocal;
    private boolean isConnectionConsumer;
-   private MessageCallbackHandler messageCallbackHandler;
+   private ClientConsumer clientConsumer;
    private int bufferSize;
    private int maxDeliveries;
 
@@ -137,8 +137,8 @@
 
       // We need to synchronize the old message callback handler using the new one
 
-      MessageCallbackHandler handler = oldCallbackManager.unregisterHandler(oldConsumerID);
-      MessageCallbackHandler newHandler = newCallbackManager.unregisterHandler(consumerID);
+      ClientConsumer handler = oldCallbackManager.unregisterHandler(oldConsumerID);
+      ClientConsumer newHandler = newCallbackManager.unregisterHandler(consumerID);
    
       handler.synchronizeWith(newHandler);
       newCallbackManager.registerHandler(consumerID, handler);
@@ -171,14 +171,14 @@
       return isConnectionConsumer;
    }
 
-   public void setMessageCallbackHandler(MessageCallbackHandler handler)
+   public void setClientConsumer(ClientConsumer handler)
    {
-      this.messageCallbackHandler = handler;
+      this.clientConsumer = handler;
    }
 
-   public MessageCallbackHandler getMessageCallbackHandler()
+   public ClientConsumer getClientConsumer()
    {
-      return messageCallbackHandler;
+      return clientConsumer;
    }
 
    public int getBufferSize()
@@ -205,6 +205,15 @@
    {
       return storingDeliveries;
    }
+   
+   public boolean isShouldAck()
+   {
+   	//If e are a non durable subscriber to a topic then there is no need
+   	//to send acks to the server - we wouldn't have stored them on the server side anyway
+   	
+      return !(destination.isTopic() && subscriptionName == null);
+      
+   }
 
    // Package protected ----------------------------------------------------------------------------
 

Modified: trunk/src/main/org/jboss/jms/client/state/SessionState.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/state/SessionState.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/client/state/SessionState.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -33,12 +33,12 @@
 import javax.jms.MessageListener;
 import javax.jms.Session;
 
+import org.jboss.jms.client.container.ClientConsumer;
 import org.jboss.jms.client.delegate.ClientBrowserDelegate;
 import org.jboss.jms.client.delegate.ClientConsumerDelegate;
 import org.jboss.jms.client.delegate.ClientProducerDelegate;
 import org.jboss.jms.client.delegate.ClientSessionDelegate;
 import org.jboss.jms.client.delegate.DelegateSupport;
-import org.jboss.jms.client.remoting.MessageCallbackHandler;
 import org.jboss.jms.delegate.DeliveryInfo;
 import org.jboss.jms.delegate.DeliveryRecovery;
 import org.jboss.jms.delegate.SessionDelegate;
@@ -221,7 +221,7 @@
                                       consState.getSelector(),
                                       consState.isNoLocal(),
                                       consState.getSubscriptionName(),
-                                      consState.isConnectionConsumer());
+                                      consState.isConnectionConsumer(), true);
             log.debug(this + " created new consumer " + newConsDelegate);
 
             consDelegate.synchronizeWith(newConsDelegate);
@@ -419,17 +419,17 @@
       this.recoverCalled = recoverCalled;
    }
 
-   public MessageCallbackHandler getCallbackHandler(int consumerID)
+   public ClientConsumer getCallbackHandler(int consumerID)
    {
-      return (MessageCallbackHandler)callbackHandlers.get(new Integer(consumerID));
+      return (ClientConsumer)callbackHandlers.get(new Integer(consumerID));
    }
 
-   public void addCallbackHandler(MessageCallbackHandler handler)
+   public void addCallbackHandler(ClientConsumer handler)
    {
       callbackHandlers.put(new Integer(handler.getConsumerId()), handler);
    }
 
-   public void removeCallbackHandler(MessageCallbackHandler handler)
+   public void removeCallbackHandler(ClientConsumer handler)
    {
       callbackHandlers.remove(new Integer(handler.getConsumerId()));
    }

Modified: trunk/src/main/org/jboss/jms/delegate/DeliveryInfo.java
===================================================================
--- trunk/src/main/org/jboss/jms/delegate/DeliveryInfo.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/delegate/DeliveryInfo.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -47,6 +47,9 @@
 
    private MessageProxy msg;
    
+   //For messages in non durable subscriptions - there is no need to ack on the server
+   private boolean shouldAck;
+   
    //When using the evil abomination known as a ConnectionConsumer, the connection consumer
    //will get from a session that it created, then pass them onto sessions got from the pool
    //this means when the messages are acked/cancelled then this needs to be done against
@@ -61,7 +64,7 @@
    // Constructors --------------------------------------------------
    
    public DeliveryInfo(MessageProxy msg, int consumerId, String queueName,
-                       SessionDelegate connectionConsumerSession)
+                       SessionDelegate connectionConsumerSession, boolean shouldAck)
    {      
       this.msg = msg;
       
@@ -70,6 +73,8 @@
       this.queueName = queueName;
       
       this.connectionConsumerSession = connectionConsumerSession;
+      
+      this.shouldAck = shouldAck;
    }
 
    // Public --------------------------------------------------------
@@ -94,6 +99,11 @@
       return connectionConsumerSession;
    }
    
+   public boolean isShouldAck()
+   {
+   	return shouldAck;
+   }
+   
    public String toString()
    {
       return "Delivery[" + getDeliveryID() + ", " + msg + "]";

Modified: trunk/src/main/org/jboss/jms/delegate/SessionDelegate.java
===================================================================
--- trunk/src/main/org/jboss/jms/delegate/SessionDelegate.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/delegate/SessionDelegate.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -77,7 +77,8 @@
    XAResource getXAResource();
 
    void addAsfMessage(MessageProxy m, int consumerID, String queueName,
-                      int maxDeliveries, SessionDelegate connectionConsumerDelegate);
+                      int maxDeliveries, SessionDelegate connectionConsumerDelegate,
+                      boolean shouldAck);
 
    boolean getTransacted();
 

Modified: trunk/src/main/org/jboss/jms/delegate/SessionEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/delegate/SessionEndpoint.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/delegate/SessionEndpoint.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -51,8 +51,8 @@
     */
    ConsumerDelegate createConsumerDelegate(JBossDestination destination, String selector,
                                            boolean noLocal, String subscriptionName,
-                                           boolean connectionConsumer) throws JMSException;
-
+                                           boolean connectionConsumer, boolean autoFlowControl) throws JMSException;
+   
    /**
     * @param failoverChannelID - the ID of the channel for which there is a failover process in
     *        progress. -1 means regular (non-failover) browser delegate creation.

Modified: trunk/src/main/org/jboss/jms/destination/JBossDestination.java
===================================================================
--- trunk/src/main/org/jboss/jms/destination/JBossDestination.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/destination/JBossDestination.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -90,6 +90,7 @@
             }
          }
          out.writeUTF(jb.getName());
+         out.writeBoolean(jb.direct);
       }
    }
    
@@ -104,6 +105,8 @@
       else
       {
          String name = in.readUTF();
+         
+         boolean direct = in.readBoolean();
 
          JBossDestination dest;
          
@@ -128,6 +131,8 @@
             throw new IllegalStateException("Invalid value:" + b);
          }
          
+         dest.direct = direct;
+         
          return dest;
       }
    }
@@ -137,6 +142,8 @@
 
    protected String name;
    
+   protected boolean direct;
+   
    // Constructors --------------------------------------------------
 
    public JBossDestination(String name)
@@ -168,6 +175,11 @@
    {
       return false;
    }
+   
+   public boolean isDirect()
+   {
+   	return direct;
+   }
 
    public boolean equals(Object o)
    {

Modified: trunk/src/main/org/jboss/jms/destination/JBossQueue.java
===================================================================
--- trunk/src/main/org/jboss/jms/destination/JBossQueue.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/destination/JBossQueue.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -46,6 +46,13 @@
    {
       super(name);
    }
+   
+   public JBossQueue(String name, boolean direct)
+   {
+   	super(name);
+   	
+   	this.direct = direct;
+   }
 
    // JBossDestination overrides ------------------------------------
 

Modified: trunk/src/main/org/jboss/jms/message/JBossMessage.java
===================================================================
--- trunk/src/main/org/jboss/jms/message/JBossMessage.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/message/JBossMessage.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -46,7 +46,7 @@
 import org.jboss.jms.destination.JBossDestination;
 import org.jboss.jms.exception.MessagingJMSException;
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.message.MessageSupport;
+import org.jboss.messaging.core.impl.message.MessageSupport;
 import org.jboss.util.Primitives;
 import org.jboss.util.Strings;
 

Modified: trunk/src/main/org/jboss/jms/server/ConnectionFactoryManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/ConnectionFactoryManager.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/ConnectionFactoryManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,7 +23,7 @@
 
 import org.jboss.jms.client.plugin.LoadBalancingFactory;
 import org.jboss.jms.server.connectionfactory.JNDIBindings;
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
+import org.jboss.messaging.core.contract.MessagingComponent;
 
 /**
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>

Modified: trunk/src/main/org/jboss/jms/server/ConnectionManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/ConnectionManager.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/ConnectionManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -24,7 +24,7 @@
 import java.util.List;
 
 import org.jboss.jms.delegate.ConnectionEndpoint;
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
+import org.jboss.messaging.core.contract.MessagingComponent;
 
 
 /**

Modified: trunk/src/main/org/jboss/jms/server/ConnectorManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/ConnectorManager.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/ConnectorManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -21,7 +21,7 @@
   */
 package org.jboss.jms.server;
 
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
+import org.jboss.messaging.core.contract.MessagingComponent;
 
 /**
  * 

Modified: trunk/src/main/org/jboss/jms/server/DestinationManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/DestinationManager.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/DestinationManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -24,7 +24,7 @@
 import java.util.Set;
 
 import org.jboss.jms.server.destination.ManagedDestination;
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
+import org.jboss.messaging.core.contract.MessagingComponent;
 
 /**
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>

Modified: trunk/src/main/org/jboss/jms/server/JMSCondition.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/JMSCondition.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/JMSCondition.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -21,8 +21,8 @@
  */
 package org.jboss.jms.server;
 
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.contract.Condition;
+import org.jboss.messaging.core.contract.Condition;
+import org.jboss.messaging.core.contract.MessageReference;
 
 /**
  * A JMSCondition
@@ -50,7 +50,7 @@
 
    // cache the hash code
    private int hash = -1;
-
+   
    // Constructors ---------------------------------------------------------------------------------
 
    public JMSCondition(boolean queue, String name)
@@ -79,11 +79,6 @@
 
    // Condition implementation ---------------------------------------------------------------------
 
-   public boolean matches(Condition routingCondition, MessageReference ref)
-   {
-      return equals(routingCondition);
-   }
-
    public String toText()
    {
       return (queue ? QUEUE_PREFIX : TOPIC_PREFIX) + name;

Modified: trunk/src/main/org/jboss/jms/server/JMSConditionFactory.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/JMSConditionFactory.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/JMSConditionFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -21,8 +21,8 @@
  */
 package org.jboss.jms.server;
 
-import org.jboss.messaging.core.plugin.contract.Condition;
-import org.jboss.messaging.core.plugin.contract.ConditionFactory;
+import org.jboss.messaging.core.contract.Condition;
+import org.jboss.messaging.core.contract.ConditionFactory;
 
 /**
  * 

Modified: trunk/src/main/org/jboss/jms/server/ServerPeer.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/ServerPeer.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/ServerPeer.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,7 +23,6 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
-import java.io.Serializable;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -52,21 +51,21 @@
 import org.jboss.jms.server.security.SecurityMetadataStore;
 import org.jboss.jms.wireformat.JMSWireFormat;
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.Queue;
-import org.jboss.messaging.core.memory.MemoryManager;
-import org.jboss.messaging.core.memory.SimpleMemoryManager;
-import org.jboss.messaging.core.message.SimpleMessageStore;
-import org.jboss.messaging.core.plugin.IDManager;
-import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.plugin.contract.PostOffice;
-import org.jboss.messaging.core.plugin.contract.ReplicationListener;
-import org.jboss.messaging.core.plugin.contract.Replicator;
-import org.jboss.messaging.core.plugin.postoffice.Binding;
-import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
-import org.jboss.messaging.core.plugin.postoffice.cluster.FailoverStatus;
-import org.jboss.messaging.core.tx.TransactionRepository;
+import org.jboss.messaging.core.contract.Binding;
+import org.jboss.messaging.core.contract.ClusterNotifier;
+import org.jboss.messaging.core.contract.MemoryManager;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.PersistenceManager;
+import org.jboss.messaging.core.contract.PostOffice;
+import org.jboss.messaging.core.contract.Queue;
+import org.jboss.messaging.core.contract.Replicator;
+import org.jboss.messaging.core.impl.DefaultClusterNotifier;
+import org.jboss.messaging.core.impl.FailoverWaiter;
+import org.jboss.messaging.core.impl.IDManager;
+import org.jboss.messaging.core.impl.clusterconnection.ClusterConnectionManager;
+import org.jboss.messaging.core.impl.memory.SimpleMemoryManager;
+import org.jboss.messaging.core.impl.message.SimpleMessageStore;
+import org.jboss.messaging.core.impl.tx.TransactionRepository;
 import org.jboss.messaging.util.ExceptionUtil;
 import org.jboss.messaging.util.Util;
 import org.jboss.messaging.util.Version;
@@ -90,7 +89,7 @@
  *
  * $Id$
  */
-public class ServerPeer extends ServiceMBeanSupport implements ServerPeerMBean
+public class ServerPeer extends ServiceMBeanSupport
 {
    // Constants ------------------------------------------------------------------------------------
 
@@ -119,8 +118,6 @@
    // the destination
    private int defaultMaxDeliveryAttempts = 10;
 
-   private Object failoverStatusLock;
-   
    // Default is 1 minute
    private long failoverStartTimeout = 60 * 1000;
    
@@ -131,9 +128,15 @@
    
    private long defaultRedeliveryDelay;
    
-   private long queueStatsSamplePeriod = 10000;
+   private long messageCounterSamplePeriod = 10000;
    
    private int defaultMessageCounterHistoryDayLimit;
+   
+   private String clusterPullConnectionFactoryName;
+   
+   private boolean useXAForMessagePull;
+   
+   private boolean defaultPreserveOrdering;
       
    // wired components
 
@@ -149,6 +152,9 @@
    private MemoryManager memoryManager;  
    private MessageStore messageStore;
    private MessageCounterManager messageCounterManager;
+   private ClusterConnectionManager clusterConnectionManager;
+   private ClusterNotifier clusterNotifier;
+   private FailoverWaiter failoverWaiter;   
 
    // plugins
 
@@ -177,8 +183,6 @@
 
       version = Version.instance();
       
-      failoverStatusLock = new Object();
-      
       sessions = new ConcurrentReaderHashMap();
 
       started = false;
@@ -235,7 +239,19 @@
          messageStore = new SimpleMessageStore();
          txRepository =
             new TransactionRepository(persistenceManager, messageStore, transactionIDManager);
-         messageCounterManager = new MessageCounterManager(queueStatsSamplePeriod);
+         messageCounterManager = new MessageCounterManager(messageCounterSamplePeriod);
+                
+         clusterNotifier = new DefaultClusterNotifier();             
+         clusterNotifier.registerListener(connFactoryJNDIMapper);
+         failoverWaiter = new FailoverWaiter(serverPeerID, failoverStartTimeout, failoverCompleteTimeout, txRepository);
+         clusterNotifier.registerListener(failoverWaiter);
+         
+         if (clusterPullConnectionFactoryName != null)
+         {         
+	         clusterConnectionManager = new ClusterConnectionManager(useXAForMessagePull, serverPeerID, clusterPullConnectionFactoryName);
+	         clusterNotifier.registerListener(clusterConnectionManager);
+         }
+         
 
          // Start the wired components
 
@@ -250,6 +266,7 @@
          messageStore.start();
          securityStore.start();
          txRepository.start();
+         clusterConnectionManager.start();
          
          // Note we do not start the message counter manager by default. This must be done
          // explicitly by the user by calling enableMessageCounters(). This is because message
@@ -320,7 +337,9 @@
          txRepository = null;
          messageCounterManager.stop();
          messageCounterManager = null;
-
+         clusterConnectionManager.stop();
+         clusterConnectionManager = null;
+         
          unloadServerAOPConfig();
 
          // TODO unloadClientAOPConfig();
@@ -507,24 +526,24 @@
       this.defaultMaxDeliveryAttempts = attempts;
    }
    
-   public synchronized long getQueueStatsSamplePeriod()
+   public synchronized long getMessageCounterSamplePeriod()
    {
-      return queueStatsSamplePeriod;
+      return messageCounterSamplePeriod;
    }
 
-   public synchronized void setQueueStatsSamplePeriod(long newPeriod)
+   public synchronized void setMessageCounterSamplePeriod(long newPeriod)
    {
       if (newPeriod < 1000)
       {
-         throw new IllegalArgumentException("Cannot set QueueStatsSamplePeriod < 1000 ms");
+         throw new IllegalArgumentException("Cannot set MessageCounterSamplePeriod < 1000 ms");
       }
       
-      if (messageCounterManager != null && newPeriod != queueStatsSamplePeriod)
+      if (messageCounterManager != null && newPeriod != messageCounterSamplePeriod)
       {
          messageCounterManager.reschedule(newPeriod);
       }            
       
-      this.queueStatsSamplePeriod = newPeriod;
+      this.messageCounterSamplePeriod = newPeriod;
    }
    
    public synchronized long getDefaultRedeliveryDelay()
@@ -552,6 +571,48 @@
       this.defaultMessageCounterHistoryDayLimit = limit;
    }
    
+   public String getClusterPullConnectionFactoryName()
+   {
+   	return clusterPullConnectionFactoryName;
+   }
+   
+   public void setClusterPullConnectionFactoryName(String name)
+   {
+      if (started)
+      {
+         throw new IllegalStateException("Cannot set ClusterPullConnectionFactoryName while the service is running");
+      }
+   	this.clusterPullConnectionFactoryName = name;
+   }
+   
+   public boolean isUseXAForMessagePull()
+   {
+   	return useXAForMessagePull;
+   }
+   
+   public void setUseXAForMessagePull(boolean useXA)
+   {
+   	if (started)
+      {
+         throw new IllegalStateException("Cannot set UseXAForMessagePull while the service is running");
+      }
+   	this.useXAForMessagePull = useXA;
+   }
+   
+   public boolean isDefaultPreserveOrdering()
+   {
+   	return defaultPreserveOrdering;
+   }
+   
+   public void setDefaultPreserveOrdering(boolean preserve)
+   {
+   	if (started)
+      {
+         throw new IllegalStateException("Cannot set DefaultPreserveOrdering while the service is running");
+      }
+   	this.defaultPreserveOrdering = preserve;
+   }
+   
    public synchronized void setServerPeerID(int serverPeerID)
    {
       if (started)
@@ -987,8 +1048,7 @@
          
          try
          {         
-            dest = (ManagedQueue)getServer().
-               getAttribute(defaultDLQObjectName, "Instance");
+            dest = (ManagedQueue)getServer().getAttribute(defaultDLQObjectName, "Instance");
          }
          catch (InstanceNotFoundException e)
          {
@@ -997,13 +1057,18 @@
          
          if (dest != null)
          {            
-            PostOffice po = getPostOfficeInstance();
+            Binding binding = postOffice.getBindingForQueueName(dest.getName());
             
-            Binding binding = po.getBindingForQueueName(dest.getName());
+            if (binding == null)
+            {
+            	throw new IllegalStateException("Cannot find binding for queue " + dest.getName());
+            }
             
-            if (binding != null && binding.getQueue().isActive())
+            Queue queue = binding.queue;
+            
+            if (queue.isActive())
             {
-               dlq =  binding.getQueue();
+            	dlq = queue;
             }
          }
       }
@@ -1021,8 +1086,7 @@
          
          try
          {         
-            dest = (ManagedQueue)getServer().
-               getAttribute(defaultExpiryQueueObjectName, "Instance");
+            dest = (ManagedQueue)getServer().getAttribute(defaultExpiryQueueObjectName, "Instance");
          }
          catch (InstanceNotFoundException e)
          {
@@ -1031,20 +1095,25 @@
 
          if (dest != null)
          {            
-            PostOffice po = getPostOfficeInstance();
+         	Binding binding = postOffice.getBindingForQueueName(dest.getName());
             
-            Binding binding = po.getBindingForQueueName(dest.getName());
+            if (binding == null)
+            {
+            	throw new IllegalStateException("Cannot find binding for queue " + dest.getName());
+            }
             
-            if (binding != null && binding.getQueue().isActive())
+            Queue queue = binding.queue;            
+         	
+            if (queue.isActive())
             {
-               expiryQueue =  binding.getQueue();
+            	expiryQueue = queue;
             }
          }
       }
       
       return expiryQueue;
    }
-
+      
    public TransactionRepository getTxRepository()
    {
       return txRepository;
@@ -1120,148 +1189,40 @@
          // a bit messy but we have a circular dependency POJOContainer should be able to help us
          // here. Yes, this is nasty.
 
-         if (!postOffice.isLocal())
+         if (postOffice.isClustered())
          {
             Replicator rep = (Replicator)postOffice;
-            connFactoryJNDIMapper.injectReplicator(rep);            
-            rep.registerListener(new FailoverListener());
+            
+            connFactoryJNDIMapper.injectReplicator(rep);          
+            
+            // Also inject into the cluster connection manager
+            
+            this.clusterConnectionManager.injectPostOffice(postOffice);
+            
+            this.clusterConnectionManager.injectReplicator((Replicator)postOffice);
          }
          
          // Also need to inject into txRepository
-         txRepository.injectPostOffice(postOffice);
+         txRepository.injectPostOffice(postOffice);                          
       }
       return postOffice;
    }
 
-   public Replicator getReplicator() throws Exception
+   public ClusterNotifier getClusterNotifier()
    {
-      PostOffice postOffice = getPostOfficeInstance();
-      if (!(postOffice instanceof Replicator))
-      {
-         throw new  IllegalAccessException("This operations is only legal on clustering configurations");
-      }
-      return (Replicator)postOffice;
+   	return clusterNotifier;
    }
+   
+   public FailoverWaiter getFailoverWaiter()
+   {
+   	return failoverWaiter;
+   }
 
    public synchronized int getNextObjectID()
    {
       return objectIDSequence++;
    }
-
-   /*
-    * Wait for failover from the specified node to complete.
-    */
-   public int waitForFailover(int failedNodeID) throws Exception
-   {
-      // This node may be failing over for another node - in which case we must wait for that to be
-      // complete.
-      
-      log.debug(this + " waiting for server-side failover for failed node " + failedNodeID + " to complete");
-      
-      Replicator replicator = getReplicator();
-
-      long startToWait = getFailoverStartTimeout();
-      long completeToWait = getFailoverCompleteTimeout();
-                     
-      // Must lock here
-      synchronized (failoverStatusLock)
-      {         
-         while (true)
-         {         
-            //TODO we shouldn't have a dependency on DefaultClusteredPostOffice - where should we put the constants?
-
-            Map replicants = replicator.get(DefaultClusteredPostOffice.FAILED_OVER_FOR_KEY);
-            
-            boolean foundEntry = false;
-                        
-            if (replicants != null)
-            {
-               for(Iterator i = replicants.entrySet().iterator(); i.hasNext(); )
-               {
-                  Map.Entry entry = (Map.Entry)i.next();
-                  Integer nid = (Integer)entry.getKey();
-                  FailoverStatus status = (FailoverStatus)entry.getValue();
-                  
-                  if (status.isFailedOverForNode(failedNodeID))
-                  {
-                     log.debug(this + ": failover is complete on node " + nid);
-                     return nid.intValue();
-                  }
-                  else if (status.isFailingOverForNode(failedNodeID))
-                  {
-                     log.debug(this + ": fail over is in progress on node " + nid);
-                     
-                     // A server has started failing over for the failed node, but not completed.
-                     // If it's not this node then we immediately return so the connection can be
-                     // redirected to another node.
-                     if (nid.intValue() != this.getServerPeerID())
-                     {
-                        return nid.intValue();
-                     }
-                     
-                     // Otherwise we wait for failover to complete
-                     
-                     if (completeToWait <= 0)
-                     {
-                        // Give up now
-                        log.debug(this + " already waited long enough for failover to complete, giving up");
-                        return -1;
-                     }
-                     
-                     // Note - we have to count the time since other unrelated nodes may fail and
-                     // wake up the lock - in this case we don't want to give up too early.
-                     long start = System.currentTimeMillis();
-
-                     try
-                     {
-                        log.debug(this + " blocking on the failover lock, waiting for failover to complete");
-                        failoverStatusLock.wait(completeToWait);
-                        log.debug(this + " releasing the failover lock, checking again whether failover completed ...");
-                     }
-                     catch (InterruptedException ignore)
-                     {                  
-                     }
-                     completeToWait -= System.currentTimeMillis() - start;
-                     foundEntry = true;
-                  }
-               }        
-            }
-            
-            if (!foundEntry)
-            {              
-               // No trace of failover happening so we wait a maximum of FAILOVER_START_TIMEOUT for
-               // some replicated data to arrive. This should arrive fairly quickly since this is
-               // added at the beginning of the failover process. If it doesn't arrive it would
-               // imply that no failover has actually happened on the server or the timeout is too
-               // short. It is possible that no failover has actually happened on the server, if for
-               // example there is a problem with the client side network but the server side
-               // network is ok.
-   
-               if (startToWait <= 0)
-               {
-                  // Don't want to wait again
-                  log.debug(this + " already waited long enough for failover to start, giving up");
-                  return -1;
-               }
-               
-               // Note - we have to count the time since other unrelated nodes may fail and wake
-               // up the lock - in this case we don't want to give up too early.
-               long start = System.currentTimeMillis(); 
-               try
-               {
-                  log.debug(this + " blocking on the failover lock, waiting for failover to start");
-                  failoverStatusLock.wait(startToWait);
-                  log.debug(this + " releasing the failover lock, checking again whether failover started ...");
-               }
-               catch (InterruptedException ignore)
-               {                  
-               }
-               startToWait -= System.currentTimeMillis() - start;              
-            }
-         }        
-      }
-   }
-   
+         
    public String toString()
    {
       return "ServerPeer[" + getServerPeerID() + "]";
@@ -1272,7 +1233,7 @@
    // Protected ------------------------------------------------------------------------------------
 
    // Private --------------------------------------------------------------------------------------
-  
+     
    private void loadServerAOPConfig() throws Exception
    {
       URL url = this.getClass().getClassLoader().getResource("aop-messaging-server.xml");
@@ -1446,7 +1407,7 @@
    /*
     * Undeploy the MBean and delete the underlying data
     */
-   private boolean destroyDestination(boolean isQueue, String name) throws Exception
+   private boolean destroyDestination(boolean isQueue, String name) throws Throwable
    {
       String destType = isQueue ? "Queue" : "Topic";
       String ons ="jboss.messaging.destination:service=" + destType + ",name=" + name;
@@ -1460,130 +1421,32 @@
          return false;
       }
                   
-      //First deactivate
-      
-      if (isQueue)
-      {
-         Binding binding = postOffice.getBindingForQueueName(name);
-         
-         if (binding != null)
-         {
-            binding.getQueue().deactivate();
-         }
-      }
-      else
-      {
-         JMSCondition topicCond = new JMSCondition(false, name);    
-         
-         Collection bindings = postOffice.getBindingsForCondition(topicCond);
-         
-         Iterator iter = bindings.iterator();
-         while (iter.hasNext())            
-         {
-            Binding binding = (Binding)iter.next();
-            
-            binding.getQueue().deactivate();
-         }
-      }
-            
-      //Delete any message data
-      
-      mbeanServer.invoke(on, "removeAllMessages", null, null);
-      
       //undeploy the mbean
       if (!undeployDestination(isQueue, name))
       {
          return false;
       }
             
-      //Unbind from the post office
+      //Unbind the destination's queues
       
-      if (isQueue)
+      JMSCondition condition = new JMSCondition(isQueue, name);  
+      
+      Collection queues = postOffice.getQueuesForCondition(condition, true);
+      
+      Iterator iter = queues.iterator();
+      
+      while (iter.hasNext())            
       {
-         Binding binding = postOffice.getBindingForQueueName(name);
+         Queue queue = (Queue)iter.next();
          
-         if (binding != null)
-         {
-            try
-            {
-               Queue queue = binding.getQueue();
-               if (!queue.isClustered())
-               {
-                  postOffice.unbindQueue(queue.getName());
-               }
-               else
-               {
-                  ((ClusteredPostOffice)postOffice).unbindClusteredQueue(queue.getName());
-               }
-            }
-            catch (Throwable t)
-            {
-               throw new Exception("Failed to unbind queue", t);
-            }
-         }
+         postOffice.removeBinding(queue.getName(), false);
       }
-      else
-      {
-         JMSCondition topicCond = new JMSCondition(false, name);    
-         
-         Collection bindings = postOffice.getBindingsForCondition(topicCond);
-         
-         Iterator iter = bindings.iterator();
-         while (iter.hasNext())            
-         {
-            Binding binding = (Binding)iter.next();
-            
-            try
-            {
-               postOffice.unbindQueue(binding.getQueue().getName());
-            }
-            catch (Throwable t)
-            {
-               throw new Exception("Failed to unbind queue", t);
-            }
-         }
-      }
+      
       return true;
    }
    
 
    // Inner classes --------------------------------------------------------------------------------
    
-   private class FailoverListener implements ReplicationListener
-   {
-      public void onReplicationChange(Serializable key, Map updatedReplicantMap,
-                                      boolean added, int originatingNodeId)
-      {
-         if (key.equals(DefaultClusteredPostOffice.FAILED_OVER_FOR_KEY))
-         {
-            if (updatedReplicantMap != null && originatingNodeId == serverPeerID)
-            {
-               FailoverStatus status =
-                  (FailoverStatus)updatedReplicantMap.get(new Integer(serverPeerID));
-               
-               if (status != null && status.isFailedOver())
-               {                     
-                  // We prompt txRepository to load any prepared txs - so we can take over
-                  // responsibility for in doubt transactions from other nodes
-                  try
-                  {
-                     txRepository.loadPreparedTransactions();
-                  }
-                  catch (Exception e)
-                  {
-                     log.error("Failed to load prepared transactions", e);
-                  }
-               }
-            }
-            
-            synchronized (failoverStatusLock)
-            {
-               log.debug(ServerPeer.this +
-                  ".FailoverListener got failover event, notifying those waiting on lock");
-               
-               failoverStatusLock.notifyAll();
-            }
-         }         
-      }      
-   }
+  
 }

Deleted: trunk/src/main/org/jboss/jms/server/ServerPeerMBean.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/ServerPeerMBean.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/ServerPeerMBean.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,162 +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.util.List;
-import java.util.Set;
-
-import javax.management.ObjectName;
-
-import org.w3c.dom.Element;
-
-/**
- * A ServerPeerMBean
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public interface ServerPeerMBean
-{
-   // JMX attributes
-   
-   int getServerPeerID();
-   
-   void setServerPeerID(int serverPeerID);
-   
-   String getJMSVersion();
-
-   int getJMSMajorVersion();
-
-   int getJMSMinorVersion();
-
-   String getJMSProviderName();
-
-   String getProviderVersion();
-
-   int getProviderMajorVersion();
-
-   int getProviderMinorVersion();
-
-   String getDefaultQueueJNDIContext();
-   
-   void setDefaultQueueJNDIContext(String defaultQueueJNDIContext);
-
-   String getDefaultTopicJNDIContext();
-   
-   void setDefaultTopicJNDIContext(String defaultQueueJNDIContext);
-   
-   void setSecurityDomain(String securityDomain) throws Exception;
-
-   String getSecurityDomain();
-
-   void setDefaultSecurityConfig(Element conf) throws Exception;
-
-   Element getDefaultSecurityConfig();
-   
-   ObjectName getPersistenceManager();
-
-   void setPersistenceManager(ObjectName on);
-
-   ObjectName getPostOffice();
-
-   void setPostOffice(ObjectName on);
-
-   ObjectName getJmsUserManager();
-
-   void setJMSUserManager(ObjectName on);
-   
-   ObjectName getDefaultDLQ();
-
-   void setDefaultDLQ(ObjectName on);
-   
-   ObjectName getDefaultExpiryQueue();
-
-   void setDefaultExpiryQueue(ObjectName on);
- 
-   long getFailoverStartTimeout();
-   
-   void setFailoverStartTimeout(long timeout);
-   
-   long getFailoverCompleteTimeout();
-   
-   void setFailoverCompleteTimeout(long timeout);
-   
-   int getDefaultMaxDeliveryAttempts();
-
-   void setDefaultMaxDeliveryAttempts(int attempts);   
-   
-   long getQueueStatsSamplePeriod();
-
-   void setQueueStatsSamplePeriod(long newPeriod);
-   
-   long getDefaultRedeliveryDelay();
-   
-   void setDefaultRedeliveryDelay(long delay);
-   
-   int getDefaultMessageCounterHistoryDayLimit();
-   
-   void setDefaultMessageCounterHistoryDayLimit(int limit);
-   
-   List getMessageCounters() throws Exception;
-   
-   List getMessageStatistics() throws Exception;
-   
-   Set getDestinations() throws Exception;
-   
-   
-   // JMX operations
-   
-   String deployQueue(String name, String jndiName) throws Exception;
-
-   String deployQueue(String name, String jndiName, int fullSize, int pageSize, int downCacheSize)
-      throws Exception;
-
-   boolean destroyQueue(String name) throws Exception;
-   
-   boolean undeployQueue(String name) throws Exception;
-
-   String deployTopic(String name, String jndiName) throws Exception;
-
-   String deployTopic(String name, String jndiName, int fullSize, int pageSize, int downCacheSize)
-      throws Exception;
-
-   boolean destroyTopic(String name) throws Exception;
-   
-   boolean undeployTopic(String name) throws Exception;
-
-   String listMessageCountersAsHTML() throws Exception;
-   
-   void resetAllMessageCounters();
-   
-   void resetAllMessageCounterHistories();
-   
-   List retrievePreparedTransactions();
-
-   String showPreparedTransactionsAsHTML();
-   
-   void enableMessageCounters();
-   
-   void disableMessageCounters();
-}

Modified: trunk/src/main/org/jboss/jms/server/bridge/Bridge.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/bridge/Bridge.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/bridge/Bridge.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -42,7 +42,7 @@
 import javax.transaction.xa.XAResource;
 
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
+import org.jboss.messaging.core.contract.MessagingComponent;
 import org.jboss.tm.TransactionManagerLocator;
 import org.jboss.tm.TxManager;
 
@@ -204,10 +204,6 @@
       this.lock = new Object();      
    }
    
-   
-   /*
-    * This constructor is used when source and destination are on different servers
-    */
    public Bridge(ConnectionFactoryFactory sourceCff, ConnectionFactoryFactory destCff,
                  Destination sourceDestination, Destination targetDestination,         
                  String sourceUsername, String sourcePassword,

Modified: trunk/src/main/org/jboss/jms/server/bridge/BridgeService.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/bridge/BridgeService.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/bridge/BridgeService.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -28,8 +28,7 @@
 import javax.naming.Context;
 import javax.naming.InitialContext;
 
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
-import org.jboss.messaging.core.plugin.contract.ServerPlugin;
+import org.jboss.messaging.core.contract.MessagingComponent;
 import org.jboss.system.ServiceMBeanSupport;
 
 /**
@@ -41,8 +40,7 @@
  * $Id$
  *
  */
-public class BridgeService extends ServiceMBeanSupport
-   implements ServerPlugin, BridgeMBean
+public class BridgeService extends ServiceMBeanSupport implements BridgeMBean
 {
    private Bridge bridge;
    

Modified: trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactory.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactory.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -350,11 +350,6 @@
 
    // Public ---------------------------------------------------------------------------------------
 
-   public String toString()
-   {
-      return "[" + jndiBindings.toString() + "]";
-   }
-
    // Package protected ----------------------------------------------------------------------------
 
    // Protected ------------------------------------------------------------------------------------

Modified: trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactoryJNDIMapper.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactoryJNDIMapper.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactoryJNDIMapper.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -21,7 +21,6 @@
  */
 package org.jboss.jms.server.connectionfactory;
 
-import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -30,7 +29,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import javax.naming.Context;
 import javax.naming.InitialContext;
@@ -50,10 +48,9 @@
 import org.jboss.jms.server.endpoint.advised.ConnectionFactoryAdvised;
 import org.jboss.jms.wireformat.Dispatcher;
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.plugin.contract.FailoverMapper;
-import org.jboss.messaging.core.plugin.contract.ReplicationListener;
-import org.jboss.messaging.core.plugin.contract.Replicator;
-import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
+import org.jboss.messaging.core.contract.ClusterNotification;
+import org.jboss.messaging.core.contract.ClusterNotificationListener;
+import org.jboss.messaging.core.contract.Replicator;
 import org.jboss.messaging.util.JNDIUtil;
 import org.jboss.messaging.util.Version;
 
@@ -66,14 +63,12 @@
  * $Id$
  */
 public class ConnectionFactoryJNDIMapper
-   implements ConnectionFactoryManager, ReplicationListener
+   implements ConnectionFactoryManager, ClusterNotificationListener
 {
    // Constants ------------------------------------------------------------------------------------
 
    private static final Logger log = Logger.getLogger(ConnectionFactoryJNDIMapper.class);
 
-   private static final String CF_PREFIX = "CF_";
-
    // Static ---------------------------------------------------------------------------------------
 
    private static boolean trace = log.isTraceEnabled();
@@ -84,18 +79,18 @@
    protected ServerPeer serverPeer;
 
    // Map<uniqueName<String> - ServerConnectionFactoryEndpoint>
-   protected Map endpoints;
+   private Map endpoints;
 
    // Map<uniqueName<String> - ClientConnectionFactoryDelegate> (not just clustered delegates)
-   protected Map delegates;
+   private Map delegates;
 
    private Replicator replicator;
-
+   
    // Map<Integer(nodeID)->Integer(failoverNodeID)>
    // The map is updated when a node joins of leaves the cluster via the replicationListener. When
    // a new ConnectionFactories are deployed we use the cached map.
-   protected Map failoverMap;
-
+   //protected Map failoverMap;
+   
    // Constructors ---------------------------------------------------------------------------------
 
    public ConnectionFactoryJNDIMapper(ServerPeer serverPeer) throws Exception
@@ -180,13 +175,9 @@
       // connection factory list. This will happen locally too, so we will get the replication
       // message locally - to avoid updating it again we can ignore any "add" replication updates
       // that originate from the current node.
-
+      
       if (creatingClustered)
       {
-         // Replicate the change - we will ignore this locally
-      	
-         replicator.put(CF_PREFIX + uniqueName, localDelegate);
-
          // Create a clustered delegate
          
          if (!supportsLoadBalancing)
@@ -194,7 +185,7 @@
          	loadBalancingFactory = new NoLoadBalancingLoadBalancingFactory(localDelegate);
          }
 
-         Map localDelegates = replicator.get(CF_PREFIX + uniqueName);
+         Map localDelegates = replicator.get(Replicator.CF_PREFIX + uniqueName);
          delegate = createClusteredDelegate(localDelegates.values(), loadBalancingFactory, supportsFailover);
 
          log.debug(this + " created clustered delegate " + delegate);
@@ -223,6 +214,10 @@
       // Registering with the dispatcher should always be the last thing otherwise a client could
       // use a partially initialised object
       Dispatcher.instance.registerTarget(id, advised);
+
+      // Replicate the change - we will ignore this locally
+   	
+      if (replicator != null) replicator.put(Replicator.CF_PREFIX + uniqueName, localDelegate);            
    }
 
    public synchronized void unregisterConnectionFactory(String uniqueName, boolean supportsFailover, boolean supportsLoadBalancing)
@@ -267,10 +262,10 @@
          if (replicator != null)
          {
             //There may be no clustered post office deployed
-            if (!replicator.remove(CF_PREFIX + uniqueName))
+            if (!replicator.remove(Replicator.CF_PREFIX + uniqueName))
             {
                throw new IllegalStateException("Cannot find replicant to remove: " +
-                                               CF_PREFIX + uniqueName);
+               		Replicator.CF_PREFIX + uniqueName);
             }
          }
       }
@@ -291,42 +286,23 @@
    {
       initialContext.close();
 
-      if (replicator != null)
-      {
-         replicator.unregisterListener(this);
-      }
-
       log.debug("stopped");
    }
 
    // ReplicationListener interface ----------------------------------------------------------------
 
-   /**
-    * @param updatedReplicantMap Map<Integer(nodeID)-Map<>>
-    */
-   public synchronized void onReplicationChange(Serializable key, Map updatedReplicantMap,
-                                                boolean added, int originatorNodeID)
+   public synchronized void notify(ClusterNotification notification)
    {
-      log.debug(this + " received " + key + " replication change from node " + originatorNodeID +
-         ", new map " + updatedReplicantMap);
+      log.debug(this + " received notification from node " + notification.nodeID );
 
       try
-      {
-         if (!(key instanceof String))
-         {
-            return;
-         }
-
-         String sKey = (String)key;
-
-         if (sKey.equals(DefaultClusteredPostOffice.ADDRESS_INFO_KEY))
-         {
+      {      	      	
+      	if (notification.type == ClusterNotification.TYPE_NODE_JOIN || notification.type == ClusterNotification.TYPE_NODE_LEAVE)
+      	{
             // We respond to changes in the node-address mapping. This will be replicated whan a
-            // node joins / leaves the group. When this happens we need to recalculate the
-            // failoverMap and rebind all connection factories with the new mapping. We cannot just
-            // reference a single map since the objects are bound in JNDI in serialized form.
+            // node joins / leaves the group. When this happens we need to rebind all connection factories with the new mapping.
 
-            failoverMap = recalculateFailoverMap(updatedReplicantMap.keySet());
+            Map failoverMap = serverPeer.getPostOfficeInstance().getFailoverMap();
 
             // Rebind
 
@@ -349,46 +325,68 @@
                }
             }
          }
-         else if (sKey.startsWith(CF_PREFIX) && originatorNodeID != serverPeer.getServerPeerID())
+         else if ((notification.type == ClusterNotification.TYPE_REPLICATOR_PUT || notification.type == ClusterNotification.TYPE_REPLICATOR_REMOVE) &&
+         		   (notification.data instanceof String) && ((String)notification.data).startsWith(Replicator.CF_PREFIX))
          {
-            // A connection factory has been deployed / undeployed - we need to update the local
-            // delegate arrays inside the clustered connection factories with the same name. We
-            // don't recalculate the failover map since the number of nodes in the group hasn't
-            // changed. We also ignore any local changes since the cf will already be bound locally
-            // with the new local delegate in the array
+            // A connection factory has been deployed / undeployed 
 
-            String uniqueName = sKey.substring(CF_PREFIX.length());
+         	// NOTE! All connection factories MUST be deployed on all nodes!
+         	// Otherwise the server might failover onto a node which doesn't have that connection factory deployed
+            // so the connection won't be able to recconnect.
+         	
+         	String key = (String)notification.data;
+         	
+            String uniqueName = key.substring(Replicator.CF_PREFIX.length());
 
-            log.debug(this + " received '" + uniqueName +
-                                "' connection factory update " + updatedReplicantMap);
+            log.debug(this + " received '" + uniqueName +  "' connection factory deploy / undeploy");
 
-            ClientClusteredConnectionFactoryDelegate del =
-               (ClientClusteredConnectionFactoryDelegate)delegates.get(uniqueName);
-
-            if (del == null)
+            ConnectionFactoryDelegate cfd = (ConnectionFactoryDelegate)delegates.get(uniqueName);
+              
+            if (cfd == null)
             {
-               throw new IllegalStateException("Cannot find cf with name " + uniqueName);
+               //This is ok - connection factory a might be deployed on node A before being deployed on node B so
+            	//node B might get the notification before it has deployed a itself
             }
-
-            List newDels = sortDelegatesOnServerID(updatedReplicantMap.values());
-
-            ClientConnectionFactoryDelegate[] delArr =
-               (ClientConnectionFactoryDelegate[])newDels.
-                  toArray(new ClientConnectionFactoryDelegate[newDels.size()]);
-
-            del.setDelegates(delArr);
-
-            ServerConnectionFactoryEndpoint endpoint =
-               (ServerConnectionFactoryEndpoint)endpoints.get(uniqueName);
-
-            if (endpoint == null)
+            else
             {
-               throw new IllegalStateException("Cannot find endpoint with name " + uniqueName);
+               if (cfd instanceof ClientConnectionFactoryDelegate)
+               {
+               	//Non clustered - ignore
+               	
+               	//We still replicate non clustered connection factories since the ClusterPullConnectionFactory
+               	//is non clustered but needs to be available across the cluster
+               }
+               else
+               {
+               	ClientClusteredConnectionFactoryDelegate del = (ClientClusteredConnectionFactoryDelegate)cfd;
+            	
+	            	Map updatedReplicantMap = replicator.get(key);
+	            	            	
+		            List newDels = sortDelegatesOnServerID(updatedReplicantMap.values());
+		
+		            ClientConnectionFactoryDelegate[] delArr =
+		               (ClientConnectionFactoryDelegate[])newDels.
+		                  toArray(new ClientConnectionFactoryDelegate[newDels.size()]);
+		
+		            del.setDelegates(delArr);
+		
+		            ServerConnectionFactoryEndpoint endpoint =
+		               (ServerConnectionFactoryEndpoint)endpoints.get(uniqueName);
+		
+		            if (endpoint == null)
+		            {
+		               throw new IllegalStateException("Cannot find endpoint with name " + uniqueName);
+		            }
+		
+		            rebindConnectionFactory(initialContext, endpoint.getJNDIBindings(), del);
+		            
+		            Map failoverMap = serverPeer.getPostOfficeInstance().getFailoverMap();
+		
+		            log.info("****** CF DEPLOYED/UNDEPLOYED: " + delArr.length + ":" + failoverMap.size());
+		            
+		            endpoint.updateClusteredClients(delArr, failoverMap);
+               }
             }
-
-            rebindConnectionFactory(initialContext, endpoint.getJNDIBindings(), del);
-
-            endpoint.updateClusteredClients(delArr, failoverMap);
          }
       }
       catch (Exception e)
@@ -402,7 +400,6 @@
    public void injectReplicator(Replicator replicator)
    {
       this.replicator = replicator;
-      replicator.registerListener(this);
    }
 
    public String toString()
@@ -422,21 +419,10 @@
    }
 
    /**
-    * @param nodeIDs Set<Integer(nodeID)>
-    * @return Map<Integer(nodeID)->Integer(failoverNodeID)>
-    */
-   private Map recalculateFailoverMap(Set nodeIDs) throws Exception
-   {
-      FailoverMapper mapper = replicator.getFailoverMapper();
-      return mapper.generateMapping(nodeIDs);
-   }
-
-   /**
     * @param localDelegates - Collection<ClientConnectionFactoryDelegate>
     */
-   private ClientClusteredConnectionFactoryDelegate
-      createClusteredDelegate(Collection localDelegates, LoadBalancingFactory loadBalancingFactory,
-      		                  boolean supportsFailover)
+   private ClientClusteredConnectionFactoryDelegate  createClusteredDelegate(Collection localDelegates, LoadBalancingFactory loadBalancingFactory,
+      		                                                                 boolean supportsFailover)
       throws Exception
    {
       log.trace(this + " creating a clustered ConnectionFactoryDelegate based on " + localDelegates);
@@ -448,20 +434,8 @@
          (ClientConnectionFactoryDelegate[])sortedLocalDelegates.
             toArray(new ClientConnectionFactoryDelegate[sortedLocalDelegates.size()]);
 
-      // If the map is not cached - generate it now
+      Map failoverMap = serverPeer.getPostOfficeInstance().getFailoverMap();
 
-      if (failoverMap == null)
-      {
-         Map nodeAddressMap = replicator.get(DefaultClusteredPostOffice.ADDRESS_INFO_KEY);
-
-         if (nodeAddressMap == null)
-         {
-            throw new IllegalStateException("Cannot find address node mapping!");
-         }
-
-         failoverMap = recalculateFailoverMap(nodeAddressMap.keySet());
-      }
-
       LoadBalancingPolicy lbp = loadBalancingFactory.createLoadBalancingPolicy(delegates);
       
       return new ClientClusteredConnectionFactoryDelegate(delegates, failoverMap, lbp, supportsFailover);

Modified: trunk/src/main/org/jboss/jms/server/destination/DestinationServiceSupport.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/destination/DestinationServiceSupport.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/destination/DestinationServiceSupport.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -11,18 +11,10 @@
 import javax.management.InstanceNotFoundException;
 import javax.management.ObjectName;
 
-import org.jboss.jms.server.DestinationManager;
-import org.jboss.jms.server.SecurityManager;
 import org.jboss.jms.server.ServerPeer;
 import org.jboss.jms.server.messagecounter.MessageCounter;
+import org.jboss.messaging.core.contract.MessagingComponent;
 import org.jboss.messaging.util.ExceptionUtil;
-import org.jboss.messaging.core.plugin.IDManager;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.plugin.contract.PostOffice;
-import org.jboss.messaging.core.plugin.contract.ServerPlugin;
-import org.jboss.messaging.core.tx.TransactionRepository;
 import org.jboss.system.ServiceMBeanSupport;
 import org.w3c.dom.Element;
 
@@ -38,8 +30,7 @@
  *
  * $Id$
  */
-public abstract class DestinationServiceSupport extends ServiceMBeanSupport
-   implements ServerPlugin, DestinationMBean
+public abstract class DestinationServiceSupport extends ServiceMBeanSupport implements DestinationMBean
 {
    // Constants -----------------------------------------------------
 
@@ -57,22 +48,8 @@
    
    protected ManagedDestination destination;
    
-   protected PostOffice postOffice;
-      
    protected ServerPeer serverPeer;
    
-   protected DestinationManager dm;
-   
-   protected SecurityManager sm;
-   
-   protected PersistenceManager pm;
-   
-   protected MessageStore ms;
-   
-   protected TransactionRepository tr;
-   
-   protected IDManager idm;
-   
    protected int nodeId;
     
    private boolean createdProgrammatically;
@@ -105,19 +82,9 @@
       try
       {
          serverPeer = (ServerPeer)server.getAttribute(serverPeerObjectName, "Instance");
-         
-         dm = serverPeer.getDestinationManager();
-         
-         sm = serverPeer.getSecurityManager();
-         
-         pm = serverPeer.getPersistenceManagerInstance(); 
-           
-         ms = serverPeer.getMessageStore();
-         
-         tr = serverPeer.getTxRepository();
-         
-         idm = serverPeer.getChannelIDManager();
-         
+               	      
+         destination.setServerPeer(serverPeer);
+               	
          nodeId = serverPeer.getServerPeerID();
          
          String name = null;
@@ -295,7 +262,7 @@
          if (started)
          {
             // push security update to the server
-            sm.setSecurityConfig(isQueue(), destination.getName(), securityConfig);  
+            serverPeer.getSecurityManager().setSecurityConfig(isQueue(), destination.getName(), securityConfig);  
          }
    
          destination.setSecurityConfig(securityConfig);

Modified: trunk/src/main/org/jboss/jms/server/destination/ManagedDestination.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/destination/ManagedDestination.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/destination/ManagedDestination.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -26,11 +26,11 @@
 
 import org.jboss.jms.server.JMSCondition;
 import org.jboss.jms.server.ServerPeer;
-import org.jboss.messaging.core.Queue;
-import org.jboss.messaging.core.plugin.contract.Condition;
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
-import org.jboss.messaging.core.plugin.contract.PostOffice;
-import org.jboss.messaging.core.plugin.postoffice.Binding;
+import org.jboss.messaging.core.contract.Binding;
+import org.jboss.messaging.core.contract.Condition;
+import org.jboss.messaging.core.contract.MessagingComponent;
+import org.jboss.messaging.core.contract.PostOffice;
+import org.jboss.messaging.core.contract.Queue;
 import org.w3c.dom.Element;
 
 /**
@@ -206,10 +206,17 @@
       {            
          Binding binding = serverPeer.getPostOfficeInstance().getBindingForQueueName(dlq.getName());
          
-         if (binding != null && binding.getQueue().isActive())
+         if (binding == null)
          {
-            theQueue =  binding.getQueue();
+         	throw new IllegalStateException("Cannot find binding for queue " + dlq.getName());
          }
+         
+         Queue queue = binding.queue;
+         
+         if (queue.isActive())
+         {
+         	theQueue = queue;
+         }
       }
       
       return theQueue;
@@ -227,12 +234,20 @@
       
       if (expiryQueue != null)
       {            
-         Binding binding = serverPeer.getPostOfficeInstance().getBindingForQueueName(expiryQueue.getName());
-         
-         if (binding != null && binding.getQueue().isActive())
+      	Binding binding = serverPeer.getPostOfficeInstance().getBindingForQueueName(expiryQueue.getName());
+      	
+         if (binding == null)
          {
-            theQueue =  binding.getQueue();
+         	throw new IllegalStateException("Cannot find binding for queue " + expiryQueue.getName());
          }
+         
+         Queue queue = binding.queue;
+         
+      	
+      	if (queue.isActive())
+      	{
+      		theQueue = queue;
+      	}
       }
       
       return theQueue;
@@ -264,15 +279,15 @@
       
       PostOffice postOffice = serverPeer.getPostOfficeInstance();
       
-      Collection subs = postOffice.getBindingsForCondition(cond);
+      Collection subs = postOffice.getQueuesForCondition(cond, true);
       
       Iterator iter = subs.iterator();
 
       while (iter.hasNext())
       {
-         Binding binding = (Binding)iter.next();
+         Queue queue = (Queue)iter.next();
          
-         binding.getQueue().setMaxSize(maxSize);
+         queue.setMaxSize(maxSize);
       }
       
       this.maxSize = maxSize;

Modified: trunk/src/main/org/jboss/jms/server/destination/ManagedQueue.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/destination/ManagedQueue.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/destination/ManagedQueue.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -28,8 +28,8 @@
 import org.jboss.jms.server.messagecounter.MessageCounter;
 import org.jboss.jms.server.selector.Selector;
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.Queue;
-import org.jboss.messaging.core.message.Message;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.Queue;
 
 /**
  * A ManagedQueue
@@ -108,7 +108,7 @@
    
    public int getConsumersCount() throws Exception
    {
-      int count = queue.getNumberOfReceivers();
+      int count = queue.getLocalDistributor().getNumberOfReceivers();
 
       if (trace) { log.trace(this + " returning ConsumersCount = " + count); }
 

Modified: trunk/src/main/org/jboss/jms/server/destination/ManagedTopic.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/destination/ManagedTopic.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/destination/ManagedTopic.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -29,9 +29,9 @@
 import org.jboss.jms.server.JMSCondition;
 import org.jboss.jms.server.messagecounter.MessageCounter;
 import org.jboss.jms.server.selector.Selector;
-import org.jboss.messaging.core.Queue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.plugin.postoffice.Binding;
+import org.jboss.messaging.core.contract.Binding;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.Queue;
 import org.jboss.messaging.util.MessageQueueNameHelper;
 
 /**
@@ -58,16 +58,13 @@
 
    public void removeAllMessages() throws Throwable
    {
-      JMSCondition topicCond = new JMSCondition(false, name);
-      
-      Collection subs = serverPeer.getPostOfficeInstance().getBindingsForCondition(topicCond);
-      
+      Collection queues = serverPeer.getPostOfficeInstance().getQueuesForCondition(new JMSCondition(false, name), true);
+   	
       //XXX How to lock down all subscriptions?
-      Iterator iter = subs.iterator();
+      Iterator iter = queues.iterator();
       while (iter.hasNext())
       {
-         Binding binding = (Binding)iter.next();
-         Queue queue = binding.getQueue();
+         Queue queue = (Queue)iter.next();
          queue.removeAllReferences();
       }
    }
@@ -89,11 +86,9 @@
    
    public int getAllSubscriptionsCount() throws Exception
    {
-      JMSCondition topicCond = new JMSCondition(false, name);
-      
-      Collection subs = serverPeer.getPostOfficeInstance().getBindingsForCondition(topicCond);
-      
-      return subs.size();         
+      Collection queues = serverPeer.getPostOfficeInstance().getQueuesForCondition(new JMSCondition(false, name), true);
+   	
+      return queues.size();         
    }
       
    public int getDurableSubscriptionsCount() throws Exception
@@ -155,19 +150,17 @@
    
    public List getMessageCounters() throws Exception
    {
-      JMSCondition topicCond = new JMSCondition(false, name);
-      
       List counters = new ArrayList();
       
       // We deploy any queues corresponding to pre-existing durable subscriptions
-      Collection bindings = serverPeer.getPostOfficeInstance().getBindingsForCondition(topicCond);
-      Iterator iter = bindings.iterator();
+      Collection queues = serverPeer.getPostOfficeInstance().getQueuesForCondition(new JMSCondition(false, name), true);
+   	
+      Iterator iter = queues.iterator();
+      
       while (iter.hasNext())
       {
-         Binding binding = (Binding)iter.next();
+         Queue queue = (Queue)iter.next();
          
-         Queue queue = binding.getQueue();
-         
          String counterName = TopicService.SUBSCRIPTION_MESSAGECOUNTER_PREFIX + queue.getName();
          
          MessageCounter counter = serverPeer.getMessageCounterManager().getMessageCounter(counterName);
@@ -217,7 +210,7 @@
       
       Binding binding = serverPeer.getPostOfficeInstance().getBindingForQueueName(subId);
       
-      if (binding == null)
+      if (binding == null || !binding.queue.isActive())
       {
          throw new IllegalArgumentException("Cannot find subscription with id " + subId);
       }
@@ -234,7 +227,7 @@
          sel = new Selector(selector);
       }
       
-      List allMsgs = binding.getQueue().browse(sel);
+      List allMsgs = binding.queue.browse(sel);
       
       Iterator iter = allMsgs.iterator();
       
@@ -255,18 +248,14 @@
    {      
       List subs = new ArrayList();
    
-      JMSCondition topicCond = new JMSCondition(false, name);      
+      Collection queues = serverPeer.getPostOfficeInstance().getQueuesForCondition(new JMSCondition(false, name), true);
+   	
+      Iterator iter = queues.iterator();
       
-      Collection bindings = serverPeer.getPostOfficeInstance().getBindingsForCondition(topicCond);
-      
-      Iterator iter = bindings.iterator();
-      
       while (iter.hasNext())
       {
-         Binding binding = (Binding)iter.next();
+         Queue queue = (Queue)iter.next();
          
-         Queue queue = binding.getQueue();
-         
          if (type == ALL || (type == DURABLE && queue.isRecoverable()) || (type == NON_DURABLE && !queue.isRecoverable()))
          {         
             String subName = null;
@@ -291,22 +280,20 @@
    
    private int getMessageCount(int type) throws Exception
    {
-      JMSCondition topicCond = new JMSCondition(false, name);
+      Collection queues = serverPeer.getPostOfficeInstance().getQueuesForCondition(new JMSCondition(false, name), true);
+   	
+      Iterator iter = queues.iterator();
       
-      Collection subs = serverPeer.getPostOfficeInstance().getBindingsForCondition(topicCond);
-      
-      Iterator iter = subs.iterator();
-      
       int count = 0;
       
       while (iter.hasNext())
       {
-         Binding binding = (Binding)iter.next();
+         Queue queue = (Queue)iter.next();
          
-         if (type == ALL || (type == DURABLE && binding.getQueue().isRecoverable())
-             || (type == NON_DURABLE && !binding.getQueue().isRecoverable()))
+         if (type == ALL || (type == DURABLE && queue.isRecoverable())
+             || (type == NON_DURABLE && !queue.isRecoverable()))
          {            
-            count += binding.getQueue().getMessageCount();
+            count += queue.getMessageCount();
          }
       }
 
@@ -315,19 +302,17 @@
    
    private int getSubscriptionsCount(boolean durable) throws Exception
    {
-      JMSCondition topicCond = new JMSCondition(false, name);
+      Collection queues = serverPeer.getPostOfficeInstance().getQueuesForCondition(new JMSCondition(false, name), true);
+   	
+      Iterator iter = queues.iterator();
       
-      Collection subs = serverPeer.getPostOfficeInstance().getBindingsForCondition(topicCond);
-      
-      Iterator iter = subs.iterator();
-      
       int count = 0;
       
       while (iter.hasNext())
       {
-         Binding binding = (Binding)iter.next();
+         Queue queue = (Queue)iter.next();
          
-         if ((binding.getQueue().isRecoverable() && durable) || (!binding.getQueue().isRecoverable() && !durable))
+         if ((queue.isRecoverable() && durable) || (!queue.isRecoverable() && !durable))
          {
             count++;
          }
@@ -339,10 +324,8 @@
    
    private String listSubscriptionsAsHTML(int type) throws Exception
    {
-      JMSCondition topicCond = new JMSCondition(false, name);
-      
-      Collection bindings = serverPeer.getPostOfficeInstance().getBindingsForCondition(topicCond);
-           
+      Collection queues = serverPeer.getPostOfficeInstance().getQueuesForCondition(new JMSCondition(false, name), true);
+   	  
       StringBuffer sb = new StringBuffer();
       
       sb.append("<table width=\"100%\" border=\"1\" cellpadding=\"1\" cellspacing=\"1\">"  +
@@ -356,18 +339,16 @@
                   "<th>Max Size</th>"   +
                   "</tr>");
       
-      Iterator iter = bindings.iterator();
+      Iterator iter = queues.iterator();
       while (iter.hasNext())
       {
-         Binding binding = (Binding)iter.next();
-         
-         Queue queue = binding.getQueue();
-         
+         Queue queue = (Queue)iter.next();
+
          if (type == ALL || (type == DURABLE && queue.isRecoverable())
                   || (type == NON_DURABLE && !queue.isRecoverable()))
          {
             
-            String filterString = queue.getFilter() != null ? binding.getQueue().getFilter().getFilterString() : null;
+            String filterString = queue.getFilter() != null ? queue.getFilter().getFilterString() : null;
                      
             String subName = null;
             String clientID = null;

Modified: trunk/src/main/org/jboss/jms/server/destination/QueueService.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/destination/QueueService.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/destination/QueueService.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -14,11 +14,10 @@
 import org.jboss.jms.server.JMSCondition;
 import org.jboss.jms.server.messagecounter.MessageCounter;
 import org.jboss.jms.server.messagecounter.MessageStatistics;
-import org.jboss.messaging.core.Queue;
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
-import org.jboss.messaging.core.plugin.postoffice.Binding;
-import org.jboss.messaging.core.plugin.postoffice.cluster.LocalClusteredQueue;
+import org.jboss.messaging.core.contract.Binding;
+import org.jboss.messaging.core.contract.PostOffice;
+import org.jboss.messaging.core.contract.Queue;
+import org.jboss.messaging.core.impl.MessagingQueue;
 import org.jboss.messaging.util.ExceptionUtil;
 import org.jboss.messaging.util.XMLUtil;
 
@@ -64,60 +63,61 @@
       
       try
       {                           
-         postOffice = serverPeer.getPostOfficeInstance();
-         
-         destination.setServerPeer(serverPeer);
-
          // 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. Also,
          // binding might already exist.
            
-         PagingFilteredQueue queue = null;
+         PostOffice po = serverPeer.getPostOfficeInstance();
+                           
+         Binding binding = po.getBindingForQueueName(destination.getName());
          
-         Binding binding = postOffice.getBindingForQueueName(destination.getName());
-                  
+         Queue queue;
+         
+         log.info("*** starting queue service " + destination.getName());
+         
          if (binding != null)
          {                     
-            queue = (PagingFilteredQueue)binding.getQueue();
+         	log.info("***** queue already exists");
+         	
+         	queue = binding.queue;
+         	
+         	if (queue.isActive())
+         	{
+         		throw new IllegalStateException("Cannot deploy queue " + destination.getName() + " it is already deployed");
+         	}
+         	
+            queue.setPagingParams(destination.getFullSize(),
+                                  destination.getPageSize(),
+                                  destination.getDownCacheSize());  
             
-            queue.setPagingParams(destination.getFullSize(),
-                              destination.getPageSize(),
-                              destination.getDownCacheSize());
+            queue.setPreserveOrdering(serverPeer.isDefaultPreserveOrdering());
+            
             queue.load();
                
             // Must be done after load
             queue.setMaxSize(destination.getMaxSize());
+            
             queue.activate();           
          }
-                     
-         if (queue == null)
+         else
          {           
             // Create a new queue
+         	
+         	log.info("**** queue does not already exist");
             
             JMSCondition queueCond = new JMSCondition(true, destination.getName());
             
-            if (postOffice.isLocal() || !destination.isClustered())
-            {
-               queue = new PagingFilteredQueue(destination.getName(),
-                                               idm.getID(), ms, pm, true, true,
-                                               destination.getMaxSize(), null,
-                                               destination.getFullSize(), destination.getPageSize(),
-                                               destination.getDownCacheSize());
-               postOffice.bindQueue(queueCond, queue);
-            }
-            else
-            {
-               ClusteredPostOffice cpo = (ClusteredPostOffice)postOffice;
-               
-               queue = new LocalClusteredQueue((ClusteredPostOffice)postOffice, nodeId, destination.getName(),
-                        idm.getID(), ms, pm, true, true,
-                        destination.getMaxSize(), null, tr,
-                        destination.getFullSize(), destination.getPageSize(),
-                        destination.getDownCacheSize());
-               
-               cpo.bindClusteredQueue(queueCond, (LocalClusteredQueue)queue);
-               
-            }                             
+            queue = new MessagingQueue(nodeId, destination.getName(),
+            		                     serverPeer.getChannelIDManager().getID(),
+                                       serverPeer.getMessageStore(), serverPeer.getPersistenceManagerInstance(),
+                                       true,
+                                       destination.getMaxSize(), null,
+                                       destination.getFullSize(), destination.getPageSize(),
+                                       destination.getDownCacheSize(), destination.isClustered(),
+                                       serverPeer.isDefaultPreserveOrdering());
+            po.addBinding(new Binding(queueCond, queue), false);         
+            
+            queue.activate();
          }
          
          ((ManagedQueue)destination).setQueue(queue);
@@ -139,7 +139,7 @@
                   
          serverPeer.getMessageCounterManager().registerMessageCounter(counterName, counter);
                        
-         dm.registerDestination(destination);
+         serverPeer.getDestinationManager().registerDestination(destination);
         
          log.debug(this + " security configuration: " + (destination.getSecurityConfig() == null ?
             "null" : "\n" + XMLUtil.elementToString(destination.getSecurityConfig())));
@@ -159,7 +159,9 @@
    {
       try
       {
-         dm.unregisterDestination(destination);
+      	serverPeer.getDestinationManager().unregisterDestination(destination);
+      	
+      	log.info("*** stopping service " + destination.getName());
          
          Queue queue = ((ManagedQueue)destination).getQueue();
          
@@ -173,6 +175,9 @@
          }
          
          queue.deactivate();
+         
+         log.info("**** deactivated queue");
+         
          queue.unload();
          
          started = false;

Modified: trunk/src/main/org/jboss/jms/server/destination/TopicService.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/destination/TopicService.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/destination/TopicService.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -14,9 +14,8 @@
 
 import org.jboss.jms.server.JMSCondition;
 import org.jboss.jms.server.messagecounter.MessageCounter;
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
-import org.jboss.messaging.core.plugin.postoffice.Binding;
+import org.jboss.messaging.core.contract.PostOffice;
+import org.jboss.messaging.core.contract.Queue;
 import org.jboss.messaging.util.ExceptionUtil;
 import org.jboss.messaging.util.MessageQueueNameHelper;
 import org.jboss.messaging.util.XMLUtil;
@@ -65,27 +64,28 @@
       
       try
       {
-         postOffice = serverPeer.getPostOfficeInstance();
-
-         if (postOffice == null)
-          throw new IllegalArgumentException("Post Office instance not found. Check your destination configuration.");
-         destination.setServerPeer(serverPeer);
+         PostOffice po = serverPeer.getPostOfficeInstance();
          
-         JMSCondition topicCond = new JMSCondition(false, destination.getName());
+         log.info("*** deploying topic " + destination.getName());
                     
          // We deploy any queues corresponding to pre-existing durable subscriptions
-         Collection bindings = postOffice.getBindingsForCondition(topicCond);
-         Iterator iter = bindings.iterator();
+
+         Collection queues = po.getQueuesForCondition(new JMSCondition(false, destination.getName()), true);
+      	
+         log.info("Got " + queues.size() + " queues");
+         
+         Iterator iter = queues.iterator();
          while (iter.hasNext())
          {
-            Binding binding = (Binding)iter.next();
-            
-            PagingFilteredQueue queue = (PagingFilteredQueue)binding.getQueue();
+            Queue queue = (Queue)iter.next();
                      
             //TODO We need to set the paging params this way since the post office doesn't store them
             //instead we should never create queues inside the postoffice - only do it at deploy time
             queue.setPagingParams(destination.getFullSize(), destination.getPageSize(), destination.getDownCacheSize());
             
+            queue.setPreserveOrdering(serverPeer.isDefaultPreserveOrdering());
+            
+            log.info("**** loading queue");
             queue.load();
                         
             queue.activate();  
@@ -112,7 +112,7 @@
             serverPeer.getMessageCounterManager().registerMessageCounter(counterName, counter);            
          }
 
-         dm.registerDestination(destination);
+         serverPeer.getDestinationManager().registerDestination(destination);
          
          log.debug(this + " security configuration: " + (destination.getSecurityConfig() == null ?
             "null" : "\n" + XMLUtil.elementToString(destination.getSecurityConfig())));
@@ -131,7 +131,7 @@
    {
       try
       {
-         dm.unregisterDestination(destination);
+         serverPeer.getDestinationManager().unregisterDestination(destination);
          
          //When undeploying a topic, any non durable subscriptions will be removed
          //Any durable subscriptions will survive in persistent storage, but be removed
@@ -140,33 +140,24 @@
          //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
          
-         JMSCondition topicCond = new JMSCondition(false, destination.getName());         
+         PostOffice po = serverPeer.getPostOfficeInstance();
+                  
+         Collection queues = serverPeer.getPostOfficeInstance().getQueuesForCondition(new JMSCondition(false, destination.getName()), true);
+      	
+         Iterator iter = queues.iterator();
          
-         Collection bindings = postOffice.getBindingsForCondition(topicCond);
-         
-         Iterator iter = bindings.iterator();
          while (iter.hasNext())            
          {
-            Binding binding = (Binding)iter.next();
+            Queue queue = (Queue)iter.next();
             
-            PagingFilteredQueue queue = (PagingFilteredQueue)binding.getQueue();
-            
             if (!queue.isRecoverable())
             {
-               queue.removeAllReferences();
-               
                // Unbind
-               if (!queue.isClustered())
-               {
-                  postOffice.unbindQueue(queue.getName());
-               }
-               else
-               {
-                  ((ClusteredPostOffice)postOffice).unbindClusteredQueue(queue.getName());
-               }
+               po.removeBinding(queue.getName(), false);
             }
                         
             queue.deactivate();
+            
             queue.unload();
             
             //unregister counter

Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerBrowserEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerBrowserEndpoint.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerBrowserEndpoint.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -34,8 +34,8 @@
 import org.jboss.messaging.util.ExceptionUtil;
 import org.jboss.jms.wireformat.Dispatcher;
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.Channel;
-import org.jboss.messaging.core.Filter;
+import org.jboss.messaging.core.contract.Channel;
+import org.jboss.messaging.core.contract.Filter;
 
 /**
  * Concrete implementation of BrowserEndpoint.

Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -53,13 +53,14 @@
 import org.jboss.jms.wireformat.Dispatcher;
 import org.jboss.jms.wireformat.JMSWireFormat;
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PostOffice;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.messaging.core.tx.TransactionRepository;
+import org.jboss.messaging.core.contract.Binding;
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.PostOffice;
+import org.jboss.messaging.core.contract.Queue;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.core.impl.tx.TransactionRepository;
 import org.jboss.messaging.util.ExceptionUtil;
 import org.jboss.messaging.util.Util;
 import org.jboss.remoting.Client;
@@ -377,8 +378,7 @@
          }
          
          sessions.clear();
-         
-         
+                  
          synchronized (temporaryDestinations)
          {
             for(Iterator i = temporaryDestinations.iterator(); i.hasNext(); )
@@ -387,14 +387,9 @@
    
                if (dest.isQueue())
                {     
-               	if (postOffice.isLocal())
-               	{
-               		postOffice.unbindQueue(dest.getName());
-               	}
-               	else
-               	{
-               		((ClusteredPostOffice)postOffice).unbindClusteredQueue(dest.getName());
-               	}
+               	// Temporary queues must be unbound on ALL nodes of the cluster
+               	
+               	postOffice.removeBinding(dest.getName(), true);               	
                }
                else
                {
@@ -405,10 +400,9 @@
                	
                	//Sanity check
                	
-               	Collection bindings =
-                     postOffice.getBindingsForCondition(new JMSCondition(false, dest.getName()));
-                  
-                  if (!bindings.isEmpty())
+                  Collection queues = serverPeer.getPostOfficeInstance().getQueuesForCondition(new JMSCondition(false, dest.getName()), true);
+               	
+                  if (!queues.isEmpty())
                	{
                   	//This should never happen
                   	throw new IllegalStateException("Cannot delete temporary destination if it has consumer(s)");
@@ -661,14 +655,6 @@
          }
       }
 
-      // messages arriving over a failed-over connections will be give preferential treatment by
-      // routers, which will send them directly to their corresponding failover queues, not to
-      // the "local" queues, to reduce clutter and unnecessary "pull policy" revving.
-      if (failedNodeID != null)
-      {
-         msg.putHeader(Message.FAILED_NODE_ID, failedNodeID);
-      }
-
       // 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
@@ -687,8 +673,28 @@
             ref.setScheduledDeliveryTime(schedDeliveryTime);
          }
          
-         if (dest.isQueue())
+         if (dest.isDirect())
          {
+         	//Route directly to queue - temp kludge for clustering
+         	
+         	Binding binding = postOffice.getBindingForQueueName(dest.getName());
+         	
+         	if (binding == null)
+         	{
+         		throw new IllegalArgumentException("Cannot find binding for queue " + dest.getName());
+         	}
+         	
+         	Queue queue = binding.queue;
+         	
+         	Delivery del = queue.handle(null, ref, tx);
+         	
+         	if (del == null)
+         	{
+         		throw new JMSException("Failed to route " + ref + " to " + dest.getName());
+         	}
+         }
+         else if (dest.isQueue())
+         {
             if (!postOffice.route(ref, new JMSCondition(true, dest.getName()), tx))
             {
                throw new JMSException("Failed to route " + ref + " to " + dest.getName());

Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -149,7 +149,7 @@
                "connection to replace connection to failed node " + failedNodeID);
 
             // Wait for server side failover to complete
-            int failoverNodeID = serverPeer.waitForFailover(failedNodeID);
+            int failoverNodeID = serverPeer.getFailoverWaiter().waitForFailover(failedNodeID);
             
             if (failoverNodeID == -1 || failoverNodeID != serverPeer.getServerPeerID())
             {

Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -36,18 +36,15 @@
 import org.jboss.jms.wireformat.ClientDelivery;
 import org.jboss.jms.wireformat.Dispatcher;
 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.Queue;
-import org.jboss.messaging.core.Receiver;
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
-import org.jboss.messaging.core.plugin.contract.PostOffice;
-import org.jboss.messaging.core.plugin.postoffice.Binding;
-import org.jboss.messaging.core.tx.Transaction;
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.DeliveryObserver;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.PostOffice;
+import org.jboss.messaging.core.contract.Queue;
+import org.jboss.messaging.core.contract.Receiver;
+import org.jboss.messaging.core.impl.SimpleDelivery;
+import org.jboss.messaging.core.impl.tx.Transaction;
 import org.jboss.messaging.util.ExceptionUtil;
 import org.jboss.remoting.Client;
 import org.jboss.remoting.callback.Callback;
@@ -76,7 +73,7 @@
 
    private int id;
 
-   private Channel messageQueue;
+   private Queue messageQueue;
 
    private String queueName;
 
@@ -106,17 +103,19 @@
    // Must be volatile
    private volatile boolean clientAccepting;
 
-   private boolean storeDeliveries;
+   private boolean retainDeliveries;
    
    private long lastDeliveryID = -1;
    
+   private boolean remote;
+   
    // Constructors ---------------------------------------------------------------------------------
 
-   ServerConsumerEndpoint(int id, Channel messageQueue, String queueName,
-            ServerSessionEndpoint sessionEndpoint, String selector,
-            boolean noLocal, JBossDestination dest, Queue dlq,
-            Queue expiryQueue, long redeliveryDelay, int maxDeliveryAttempts)
-            throws InvalidSelectorException
+   ServerConsumerEndpoint(int id, Queue messageQueue, String queueName,
+					           ServerSessionEndpoint sessionEndpoint, String selector,
+					           boolean noLocal, JBossDestination dest, Queue dlq,
+					           Queue expiryQueue, long redeliveryDelay, int maxDeliveryAttempts,
+					           boolean remote) throws InvalidSelectorException
    {
       if (trace)
       {
@@ -131,8 +130,7 @@
 
       this.sessionEndpoint = sessionEndpoint;
 
-      this.callbackHandler = sessionEndpoint.getConnectionEndpoint()
-               .getCallbackHandler();
+      this.callbackHandler = sessionEndpoint.getConnectionEndpoint().getCallbackHandler();
 
       this.noLocal = noLocal;
 
@@ -148,6 +146,8 @@
 
       // Always start as false - wait for consumer to initiate.
       this.clientAccepting = false;
+      
+      this.remote = remote;
 
       this.startStopLock = new Object();
 
@@ -155,16 +155,13 @@
       {
          // This is a consumer of a non durable topic subscription. We don't need to store
          // deliveries since if the consumer is closed or dies the refs go too.
-         this.storeDeliveries = false;
+         this.retainDeliveries = false;
       }
       else
       {
-         this.storeDeliveries = true;
+         this.retainDeliveries = true;
       }
-
-      //For now always true - revisit later
-      storeDeliveries = true;
-
+      
       if (selector != null)
       {
          if (trace) { log.trace("creating selector:" + selector); }
@@ -176,7 +173,14 @@
       this.started = this.sessionEndpoint.getConnectionEndpoint().isStarted();
       
       // adding the consumer to the queue
-      this.messageQueue.add(this);
+      if (remote)
+      {
+      	this.messageQueue.getRemoteDistributor().add(this);
+      }
+      else
+      {
+      	this.messageQueue.getLocalDistributor().add(this);
+      }
 
       // We don't need to prompt delivery - this will come from the client in a changeRate request
 
@@ -237,24 +241,33 @@
          Message message = ref.getMessage();
 
          boolean selectorRejected = !this.accept(message);
+         
+         SimpleDelivery delivery = new SimpleDelivery(observer, ref, !selectorRejected);
 
-         SimpleDelivery delivery = new SimpleDelivery(observer, ref,
-                  !storeDeliveries, !selectorRejected);
-
          if (selectorRejected)
          {
             return delivery;
          }
-
+         
          long deliveryId;
 
-         if (storeDeliveries)
+         if (retainDeliveries)
          {
             deliveryId = sessionEndpoint.addDelivery(delivery, id, dlq, expiryQueue, redeliveryDelay, maxDeliveryAttempts);
          }
          else
          {
             deliveryId = -1;
+         	//Acknowledge it now
+         	try
+         	{
+         		//This basically just releases the memory reference
+         		delivery.acknowledge(null);
+         	}
+         	catch (Throwable t)
+         	{
+         		log.error("Failed to acknowledge delivery", t);
+         	}
          }
 
          // We send the message to the client on the current thread. The message is written onto the
@@ -474,7 +487,14 @@
    {
       if (trace) { log.trace(this + " grabbed the main lock in close() " + this); }
 
-      messageQueue.remove(this);
+      if (remote)
+      {
+      	messageQueue.getRemoteDistributor().remove(this);
+      }
+      else
+      {
+      	messageQueue.getLocalDistributor().remove(this);
+      }
 
       Dispatcher.instance.unregisterTarget(id, this);
 
@@ -483,32 +503,17 @@
 
       if (destination.isTopic())
       {
-         PostOffice postOffice = sessionEndpoint.getConnectionEndpoint()
-                  .getServerPeer().getPostOfficeInstance();
-
-         Binding binding = postOffice.getBindingForQueueName(queueName);
-
-         if (binding == null)
-         {
-         	//Sanity check
-         	throw new IllegalStateException("Cannot find binding for topic sub with queue name: " + queueName);
-         }
+         PostOffice postOffice = sessionEndpoint.getConnectionEndpoint().getServerPeer().getPostOfficeInstance();
                   
          ServerPeer sp = sessionEndpoint.getConnectionEndpoint().getServerPeer();
          
+         Queue queue = sp.getPostOfficeInstance().getBindingForQueueName(queueName).queue;        
+         
          ManagedDestination mDest = sp.getDestinationManager().getDestination(destination.getName(), false);
          
-         if (!binding.getQueue().isRecoverable())
+         if (!queue.isRecoverable())
          {
-            Queue queue = binding.getQueue();
-            if (!mDest.isClustered())
-            {
-               postOffice.unbindQueue(queue.getName());
-            }
-            else
-            {
-               ((ClusteredPostOffice)postOffice).unbindClusteredQueue(queue.getName());
-            }
+            postOffice.removeBinding(queueName, false);            
 
             if (!mDest.isTemporary())
             {
@@ -554,17 +559,17 @@
          started = false;
          
          // Any message deliveries already transit to the consumer, will just be ignored by the
-         // MessageCallbackHandler since it will be closed.
+         // ClientConsumer since it will be closed.
          //
          // To clarify, the close protocol (from connection) is as follows:
          //
-         // 1) MessageCallbackHandler::close() - any messages in buffer are cancelled to the server
+         // 1) ClientConsumer::close() - any messages in buffer are cancelled to the server
          // session, and any subsequent receive messages will be ignored.
          //
          // 2) ServerConsumerEndpoint::closing() causes stop() this flushes any deliveries yet to
          // deliver to the client callback handler.
          //
-         // 3) MessageCallbackHandler waits for all deliveries to arrive at client side
+         // 3) ClientConsumer waits for all deliveries to arrive at client side
          //
          // 4) ServerConsumerEndpoint:close() - endpoint is deregistered.
          //

Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -21,7 +21,6 @@
   */
 package org.jboss.jms.server.endpoint;
 
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -63,24 +62,22 @@
 import org.jboss.jms.server.selector.Selector;
 import org.jboss.jms.wireformat.Dispatcher;
 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.Queue;
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.IDManager;
-import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
-import org.jboss.messaging.core.plugin.contract.Condition;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.plugin.contract.PostOffice;
-import org.jboss.messaging.core.plugin.postoffice.Binding;
-import org.jboss.messaging.core.plugin.postoffice.cluster.LocalClusteredQueue;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.messaging.core.tx.TransactionException;
-import org.jboss.messaging.core.tx.TransactionRepository;
-import org.jboss.messaging.core.tx.TxCallback;
+import org.jboss.messaging.core.contract.Binding;
+import org.jboss.messaging.core.contract.Channel;
+import org.jboss.messaging.core.contract.Condition;
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.DeliveryObserver;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.PersistenceManager;
+import org.jboss.messaging.core.contract.PostOffice;
+import org.jboss.messaging.core.contract.Queue;
+import org.jboss.messaging.core.impl.IDManager;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.core.impl.tx.TransactionException;
+import org.jboss.messaging.core.impl.tx.TransactionRepository;
+import org.jboss.messaging.core.impl.tx.TxCallback;
 import org.jboss.messaging.util.ExceptionUtil;
 import org.jboss.messaging.util.MessageQueueNameHelper;
 import org.jboss.util.id.GUID;
@@ -194,12 +191,24 @@
                                                   String selector,
                                                   boolean noLocal,
                                                   String subscriptionName,
-                                                  boolean isCC) throws JMSException
+                                                  boolean isCC,
+                                                  boolean autoFlowControl) throws JMSException
    {
       try
       {
-         return createConsumerDelegateInternal(jmsDestination, selector,
-                                               noLocal, subscriptionName);
+      	//TODO This is a temporary kludge to allow creation of consumers directly on core queues for 
+      	//cluster connections
+      	//This will disappear once we move all JMS knowledge to the client side
+      	
+      	if (jmsDestination.isDirect())
+      	{
+      		return createConsumerDelegateDirect(jmsDestination.getName(), selector);
+      	}
+      	else
+      	{      	      	
+	         return createConsumerDelegateInternal(jmsDestination, selector,
+	                                               noLocal, subscriptionName);
+      	}
       }
       catch (Throwable t)
       {
@@ -392,7 +401,7 @@
 
       try
       {
-         if (postOffice.isLocal())
+         if (!postOffice.isClustered())
          {
             throw new IllegalStateException("Recovering deliveries but post office is not clustered!");
          }
@@ -428,12 +437,15 @@
             
             String queueName = (String)entry.getKey();
             
-            //Look up channel
+            //Look up the queue
+
             Binding binding = postOffice.getBindingForQueueName(queueName);
             
-            if (binding == null)
+            Queue queue = binding.queue;
+            
+            if (queue == null)
             {
-               throw new IllegalStateException("Cannot find channel with queue name: " + queueName);
+               throw new IllegalStateException("Cannot find queue with queue name: " + queueName);
             }
             
             List acks = (List)entry.getValue();
@@ -447,10 +459,8 @@
                ids.add(new Long(info.getMessageID()));
             }
             
-            Queue queue = binding.getQueue();
+            JMSCondition cond = (JMSCondition)binding.condition;
             
-            JMSCondition cond = (JMSCondition)binding.getCondition();                        
-            
             ManagedDestination dest =
                sp.getDestinationManager().getDestination(cond.getName(), cond.isQueue());
             
@@ -526,15 +536,14 @@
          int downCacheSize = connectionEndpoint.getDefaultTempQueueDownCacheSize();
          
          //Temporary destinations are clustered if the post office is clustered
-         boolean clustered = !postOffice.isLocal();
-         
+
          if (dest.isTopic())
          {
-            mDest = new ManagedTopic(dest.getName(), fullSize, pageSize, downCacheSize, clustered);
+            mDest = new ManagedTopic(dest.getName(), fullSize, pageSize, downCacheSize, postOffice.isClustered());
          }
          else
          {
-            mDest = new ManagedQueue(dest.getName(), fullSize, pageSize, downCacheSize, clustered);
+            mDest = new ManagedQueue(dest.getName(), fullSize, pageSize, downCacheSize, postOffice.isClustered());
          }
          
          mDest.setTemporary(true);
@@ -543,33 +552,20 @@
          
          if (dest.isQueue())
          {            
-            Queue coreQueue;
+            Queue coreQueue = new MessagingQueue(nodeId, dest.getName(),
+            												 idm.getID(), ms, pm, false, -1, null,
+										                   fullSize, pageSize, downCacheSize, postOffice.isClustered(),
+										                   sp.isDefaultPreserveOrdering());
 
-            if (clustered)
-            {
-               coreQueue = new LocalClusteredQueue((ClusteredPostOffice)postOffice, nodeId, dest.getName(),
-										                     idm.getID(), ms, pm, true, false,
-										                     -1, null, tr,
-										                     fullSize, pageSize, downCacheSize);
-            }
-            else
-            {
-	            coreQueue = new PagingFilteredQueue(dest.getName(),
-	                                                idm.getID(), ms, pm, true, false,
-	                                                -1, null, fullSize, pageSize, downCacheSize);
-            }
         
             Condition cond = new JMSCondition(true, dest.getName());
             
-         	// make a binding for this queue
-            if (clustered)
-            {
-            	((ClusteredPostOffice)postOffice).bindClusteredQueue(cond, (LocalClusteredQueue)coreQueue);
-            }
-            else
-            {
-            	postOffice.bindQueue(cond, coreQueue);
-            }
+         	// make a binding for this temporary queue
+            
+            // temporary queues need to bound on ALL nodes of the cluster
+            postOffice.addBinding(new Binding(cond, coreQueue), true);   
+            
+            coreQueue.activate();
          }         
       }
       catch (Throwable t)
@@ -604,30 +600,28 @@
          {
          	Binding binding = postOffice.getBindingForQueueName(dest.getName());
          	
-         	if (binding.getQueue().getNumberOfReceivers() != 0)
+         	if (binding == null)
          	{
-         		throw new IllegalStateException("Cannot delete temporary queue if it has consumer(s)");
+         		throw new IllegalStateException("Cannot find binding for queue " + dest.getName());
          	}
          	
-            //Unbind
-         	if (mDest.isClustered())
+         	if (binding.queue.getLocalDistributor().getNumberOfReceivers() != 0)
          	{
-         		((ClusteredPostOffice)postOffice).unbindClusteredQueue(dest.getName());
+         		throw new IllegalStateException("Cannot delete temporary queue if it has consumer(s)");
          	}
-         	else
-         	{
-         		postOffice.unbindQueue(dest.getName());
-         	}            
+         	
+         	// temporary queues must be unbound on ALL nodes of the cluster
+         	
+            postOffice.removeBinding(dest.getName(), true);         	        
          }
          else
          {
             //Topic            
-            Collection bindings =
-               postOffice.getBindingsForCondition(new JMSCondition(false, dest.getName()));
-            
-            if (!bindings.isEmpty())
+            Collection queues = postOffice.getQueuesForCondition(new JMSCondition(false, dest.getName()), true);         	
+                           
+            if (!queues.isEmpty())
          	{
-            	throw new IllegalStateException("Cannot delete temporary destination if it has consumer(s)");
+            	throw new IllegalStateException("Cannot delete temporary topic if it has consumer(s)");
          	}
                         
             // There is no need to explicitly unbind the subscriptions for the temp topic, this is because we
@@ -677,39 +671,24 @@
                                                   subscriptionName + " to unsubscribe");
          }
          
+         Queue sub = binding.queue;         
+         
          // Section 6.11. JMS 1.1.
          // "It is erroneous for a client to delete a durable subscription while it has an active
          // TopicSubscriber for it or while a message received by it is part of a current
          // transaction or has not been acknowledged in the session."
          
-         Queue sub = binding.getQueue();
-         
-         if (sub.getNumberOfReceivers() != 0)
+         if (sub.getLocalDistributor().getNumberOfReceivers() != 0)
          {
             throw new IllegalStateException("Cannot unsubscribe durable subscription " +
                                             subscriptionName + " since it has active subscribers");
          }
          
-         //Look up the topic
-         
-         JMSCondition topicCond = (JMSCondition)binding.getCondition();
-         
-         String topicName = topicCond.getName();
-         
-         ManagedDestination mDest = dm.getDestination(topicName, false);
-         
          //Unbind it
+         
+         // Durable subs must be unbound on ALL nodes of the cluster
     
-         if (mDest.isClustered() && !postOffice.isLocal())
-         {
-            ClusteredPostOffice cpo = (ClusteredPostOffice)postOffice;
-            
-            cpo.unbindClusteredQueue(queueName);
-         }
-         else
-         {         
-            postOffice.unbindQueue(queueName);
-         }
+         postOffice.removeBinding(sub.getName(), true);         
          
          String counterName = TopicService.SUBSCRIPTION_MESSAGECOUNTER_PREFIX + sub.getName();
          
@@ -1033,7 +1012,7 @@
          else
          {
             //Send to DLQ
-            
+         	
             JBossMessage copy = makeCopyForDLQOrExpiry(false, del);
             
             moveInTransaction(copy, del, rec.dlq);
@@ -1087,7 +1066,7 @@
       Transaction tx = tr.createTransaction();
       
       MessageReference ref = ms.reference(msg);
-                  
+                    
       try
       {               
          if (queue != null)
@@ -1144,6 +1123,69 @@
       
       if (trace) { log.trace(this + " acknowledged delivery " + ack); }
    }
+   
+   /* TODO We can combine this with createConsumerDelegateInternal once we move the distinction between queues and topics
+    * to the client side, so the server side just deals with queues named by string - i.e MessagingQueue instances
+    */
+   private ConsumerDelegate createConsumerDelegateDirect(String queueName, String selectorString) throws Throwable
+   {
+   	if (closed)
+      {
+         throw new IllegalStateException("Session is closed");
+      }
+      
+      if ("".equals(selectorString))
+      {
+         selectorString = null;
+      }
+      
+      if (trace)
+      {
+         log.trace(this + " creating direct consumer for " + queueName +
+            (selectorString == null ? "" : ", selector '" + selectorString + "'"));
+      }
+      
+      Binding binding =  postOffice.getBindingForQueueName(queueName);
+      
+      if (binding == null)
+      {
+      	throw new IllegalArgumentException("Cannot find queue with name " + queueName);
+      }
+      
+      int consumerID = connectionEndpoint.getServerPeer().getNextObjectID();
+            
+      int prefetchSize = connectionEndpoint.getPrefetchSize();
+      
+      JBossDestination dest = new JBossQueue(queueName);
+      
+      ServerConsumerEndpoint ep =
+         new ServerConsumerEndpoint(consumerID, binding.queue,
+                                    binding.queue.getName(), this, selectorString, false,
+                                    dest, null, null, sp.getDefaultRedeliveryDelay(), defaultMaxDeliveryAttempts, true);
+      
+      ConsumerAdvised advised;
+      
+      // Need to synchronized to prevent a deadlock
+      // See http://jira.jboss.com/jira/browse/JBMESSAGING-797
+      synchronized (AspectManager.instance())
+      {       
+         advised = new ConsumerAdvised(ep);
+      }
+      
+      Dispatcher.instance.registerTarget(consumerID, advised);
+      
+      ClientConsumerDelegate stub =
+         new ClientConsumerDelegate(consumerID, prefetchSize, defaultMaxDeliveryAttempts);
+      
+      synchronized (consumers)
+      {
+         consumers.put(new Integer(consumerID), ep);
+      }
+         
+      log.debug(this + " created and registered " + ep);    
+      
+      return stub;
+   }
 
    private ConsumerDelegate createConsumerDelegateInternal(JBossDestination jmsDestination,
                                                            String selectorString,
@@ -1169,8 +1211,7 @@
             (noLocal ? ", noLocal" : ""));
       }
 
-      ManagedDestination mDest = dm.
-         getDestination(jmsDestination.getName(), jmsDestination.isQueue());
+      ManagedDestination mDest = dm.getDestination(jmsDestination.getName(), jmsDestination.isQueue());
       
       if (mDest == null)
       {
@@ -1191,52 +1232,41 @@
       
       int consumerID = connectionEndpoint.getServerPeer().getNextObjectID();
       
-      Binding binding = null;
-      
       // Always validate the selector first
       Selector selector = null;
+      
       if (selectorString != null)
       {
          selector = new Selector(selectorString);
       }
       
+      Queue queue;
+      
       if (jmsDestination.isTopic())
-      {
-         JMSCondition topicCond = new JMSCondition(false, jmsDestination.getName());
-         
+      {         
          if (subscriptionName == null)
          {
             // non-durable subscription
             if (log.isTraceEnabled()) { log.trace(this + " creating new non-durable subscription on " + jmsDestination); }
             
             // Create the non durable sub
+            
+            queue = new MessagingQueue(nodeId, new GUID().toString(),
+							                  idm.getID(), ms, pm, false,
+							                  mDest.getMaxSize(), selector,
+							                  mDest.getFullSize(),
+							                  mDest.getPageSize(),
+							                  mDest.getDownCacheSize(),
+							                  mDest.isClustered(),
+							                  sp.isDefaultPreserveOrdering());
+            
+            JMSCondition topicCond = new JMSCondition(false, jmsDestination.getName());
                         
-            PagingFilteredQueue q;
+            postOffice.addBinding(new Binding(topicCond, queue), false);   
             
-            if (postOffice.isLocal() || !mDest.isClustered())
-            {
-               q = new PagingFilteredQueue(new GUID().toString(), idm.getID(), ms, pm, true, false,
-                        mDest.getMaxSize(), selector,
-                        mDest.getFullSize(),
-                        mDest.getPageSize(),
-                        mDest.getDownCacheSize());
-               
-               binding = postOffice.bindQueue(topicCond, q);
-            }
-            else
-            {  
-               q = new LocalClusteredQueue((ClusteredPostOffice)postOffice, nodeId, new GUID().toString(),
-                                           idm.getID(), ms, pm, true, false,
-                                           mDest.getMaxSize(), selector, tr,
-                                           mDest.getFullSize(),
-                                           mDest.getPageSize(),
-                                           mDest.getDownCacheSize());
-               
-               ClusteredPostOffice cpo = (ClusteredPostOffice)postOffice;
+            queue.activate();
 
-               binding = cpo.bindClusteredQueue(topicCond, (LocalClusteredQueue)q);
-            }
-            String counterName = TopicService.SUBSCRIPTION_MESSAGECOUNTER_PREFIX + q.getName();
+            String counterName = TopicService.SUBSCRIPTION_MESSAGECOUNTER_PREFIX + queue.getName();
   
             int dayLimitToUse = mDest.getMessageCounterHistoryDayLimit();
             if (dayLimitToUse == -1)
@@ -1248,9 +1278,7 @@
             //We don't create message counters on temp topics
             if (!mDest.isTemporary())
             {
-	            MessageCounter counter =
-	               new MessageCounter(counterName, null, q, true, false,
-	                                  dayLimitToUse);
+	            MessageCounter counter =  new MessageCounter(counterName, null, queue, true, false, dayLimitToUse);
 	            
 	            sp.getMessageCounterManager().registerMessageCounter(counterName, counter);
             }
@@ -1273,7 +1301,7 @@
             
             String name = MessageQueueNameHelper.createSubscriptionName(clientID, subscriptionName);
             
-            binding = postOffice.getBindingForQueueName(name);
+            Binding binding = postOffice.getBindingForQueueName(name);
             
             if (binding == null)
             {
@@ -1281,46 +1309,28 @@
                
                if (trace) { log.trace(this + " creating new durable subscription on " + jmsDestination); }
                               
-               PagingFilteredQueue q;
-
-               if (postOffice.isLocal())
-               {
-                  q = new PagingFilteredQueue(name, idm.getID(), ms, pm, true, true,
-                                              mDest.getMaxSize(), selector,
-                                              mDest.getFullSize(),
-                                              mDest.getPageSize(),
-                                              mDest.getDownCacheSize());
-
-                  binding = postOffice.bindQueue(topicCond, q);
-               }
-               else
-               {
-                  q = new LocalClusteredQueue((ClusteredPostOffice)postOffice, nodeId, name, idm.getID(),
-                                              ms, pm, true, true,
-                                              mDest.getMaxSize(), selector, tr,
-                                              mDest.getFullSize(),
-                                              mDest.getPageSize(),
-                                              mDest.getDownCacheSize());
-                  
-                  ClusteredPostOffice cpo = (ClusteredPostOffice)postOffice;
-                  
-                  if (mDest.isClustered())
-                  {
-                     binding = cpo.bindClusteredQueue(topicCond, (LocalClusteredQueue)q);
-                  }
-                  else
-                  {
-                     binding = cpo.bindQueue(topicCond, q);
-                  }
-               }
+               queue = new MessagingQueue(nodeId, name, idm.getID(),
+                                          ms, pm, true,
+                                          mDest.getMaxSize(), selector,
+                                          mDest.getFullSize(),
+                                          mDest.getPageSize(),
+                                          mDest.getDownCacheSize(),
+                                          mDest.isClustered(),
+                                          sp.isDefaultPreserveOrdering());
                
+               // Durable subs must be bound on ALL nodes of the cluster
+               
+               postOffice.addBinding(new Binding(new JMSCondition(false, jmsDestination.getName()), queue), true);
+               
+               queue.activate();
+                  
                //We don't create message counters on temp topics
                if (!mDest.isTemporary())
                {	               
-	               String counterName = TopicService.SUBSCRIPTION_MESSAGECOUNTER_PREFIX + q.getName();
+	               String counterName = TopicService.SUBSCRIPTION_MESSAGECOUNTER_PREFIX + queue.getName();
 	                       
 	               MessageCounter counter =
-	                  new MessageCounter(counterName, subscriptionName, q, true, true,
+	                  new MessageCounter(counterName, subscriptionName, queue, true, true,
 	                                     mDest.getMessageCounterHistoryDayLimit());
 	               
 	               sp.getMessageCounterManager().registerMessageCounter(counterName, counter);
@@ -1330,12 +1340,14 @@
             {
                //Durable sub already exists
             	
+            	queue = binding.queue;
+            	
                if (trace) { log.trace(this + " subscription " + subscriptionName + " already exists"); }
                
             	//Check if it is already has a subscriber
             	//We can't have more than one subscriber at a time on the durable sub
                
-               if (binding.getQueue().getNumberOfReceivers() > 0)
+               if (queue.getLocalDistributor().getNumberOfReceivers() > 0)
                {
                	throw new IllegalStateException("Cannot create a subscriber on the durable subscription since it already has subscriber(s)");
                }
@@ -1346,9 +1358,7 @@
                // Changing a durable subscriber is equivalent to unsubscribing (deleting) the old
                // one and creating a new one.
                
-               String filterString =
-                  binding.getQueue().getFilter() != null ?
-                     binding.getQueue().getFilter().getFilterString() : null;
+               String filterString = queue.getFilter() != null ? queue.getFilter().getFilterString() : null;
                
                boolean selectorChanged =
                   (selectorString == null && filterString != null) ||
@@ -1358,9 +1368,9 @@
                
                if (trace) { log.trace("selector " + (selectorChanged ? "has" : "has NOT") + " changed"); }
                
-               JMSCondition cond = (JMSCondition)binding.getCondition();
+               String oldTopicName = ((JMSCondition)binding.condition).getName();
                
-               boolean topicChanged = !cond.getName().equals(jmsDestination.getName());
+               boolean topicChanged = !oldTopicName.equals(jmsDestination.getName());
                
                if (log.isTraceEnabled()) { log.trace("topic " + (topicChanged ? "has" : "has NOT") + " changed"); }
                
@@ -1370,55 +1380,30 @@
                   
                   // Unbind the durable subscription
                   
-                  if (mDest.isClustered() && !postOffice.isLocal())
-                  {
-                     ClusteredPostOffice cpo = (ClusteredPostOffice)postOffice;
-                     
-                     cpo.unbindClusteredQueue(name);
-                  }
-                  else
-                  {
-                     postOffice.unbindQueue(name);
-                  }
+                  // Durable subs must be unbound on ALL nodes of the cluster
                   
+                  postOffice.removeBinding(queue.getName(), true);                  
+                  
                   // create a fresh new subscription
                                     
-                  PagingFilteredQueue q;
+                  queue = new MessagingQueue(nodeId, name, idm.getID(), ms, pm, true,
+					                              mDest.getMaxSize(), selector,
+					                              mDest.getFullSize(),
+					                              mDest.getPageSize(),
+					                              mDest.getDownCacheSize(),
+					                              mDest.isClustered(),
+					                              sp.isDefaultPreserveOrdering());
                   
-                  if (postOffice.isLocal())
-                  {
-                     q = new PagingFilteredQueue(name, idm.getID(), ms, pm, true, true,
-                              mDest.getMaxSize(), selector,
-                              mDest.getFullSize(),
-                              mDest.getPageSize(),
-                              mDest.getDownCacheSize());
-                     binding = postOffice.bindQueue(topicCond, q);
-                  }
-                  else
-                  {
-                     q = new LocalClusteredQueue((ClusteredPostOffice)postOffice, nodeId, name, idm.getID(), ms, pm, true, true,
-                              mDest.getMaxSize(), selector, tr,
-                              mDest.getFullSize(),
-                              mDest.getPageSize(),
-                              mDest.getDownCacheSize());
-                     
-                     ClusteredPostOffice cpo = (ClusteredPostOffice)postOffice;
-                     
-                     if (mDest.isClustered())
-                     {
-                        binding = cpo.bindClusteredQueue(topicCond, (LocalClusteredQueue)q);
-                     }
-                     else
-                     {
-                        binding = cpo.bindQueue(topicCond, (LocalClusteredQueue)q);
-                     }
-                  }
-                  String counterName = TopicService.SUBSCRIPTION_MESSAGECOUNTER_PREFIX + q.getName();
+                  // Durable subs must be bound on ALL nodes of the cluster
                   
+                  postOffice.addBinding(new Binding(new JMSCondition(false, jmsDestination.getName()), queue), true);
+
+                  String counterName = TopicService.SUBSCRIPTION_MESSAGECOUNTER_PREFIX + queue.getName();
+                  
                   if (!mDest.isTemporary())
                   {
 	                  MessageCounter counter =
-	                     new MessageCounter(counterName, subscriptionName, q, true, true,
+	                     new MessageCounter(counterName, subscriptionName, queue, true, true,
 	                                        mDest.getMessageCounterHistoryDayLimit());
 	                  
 	                  sp.getMessageCounterManager().registerMessageCounter(counterName, counter);
@@ -1431,12 +1416,13 @@
       {
          // Consumer on a jms queue
          
-         // Let's find the binding
-         binding = postOffice.getBindingForQueueName(jmsDestination.getName());
+         // Let's find the queue
+      	
+      	queue = postOffice.getBindingForQueueName(jmsDestination.getName()).queue;
          
-         if (binding == null)
+         if (queue == null)
          {
-            throw new IllegalStateException("Cannot find binding for jms queue: " + jmsDestination.getName());
+            throw new IllegalStateException("Cannot find queue: " + jmsDestination.getName());
          }
       }
       
@@ -1456,9 +1442,9 @@
       }
       
       ServerConsumerEndpoint ep =
-         new ServerConsumerEndpoint(consumerID, (PagingFilteredQueue)binding.getQueue(),
-                  binding.getQueue().getName(), this, selectorString, noLocal,
-                  jmsDestination, dlqToUse, expiryQueueToUse, redeliveryDelay, maxDeliveryAttemptsToUse);
+         new ServerConsumerEndpoint(consumerID, queue,
+                                    queue.getName(), this, selectorString, noLocal,
+                                    jmsDestination, dlqToUse, expiryQueueToUse, redeliveryDelay, maxDeliveryAttemptsToUse, false);
       
       ConsumerAdvised advised;
       
@@ -1511,13 +1497,16 @@
       log.debug(this + " creating browser for " + jmsDestination +
          (selector == null ? "" : ", selector '" + selector + "'"));
 
-      Binding binding = postOffice.getBindingForQueueName(jmsDestination.getName()); // TODO
-
+      Binding binding = postOffice.getBindingForQueueName(jmsDestination.getName());
+      
+      if (binding == null)
+      {
+      	throw new IllegalStateException("Cannot find queue with name " + jmsDestination.getName());
+      }
+      
       int browserID = connectionEndpoint.getServerPeer().getNextObjectID();
 
-      ServerBrowserEndpoint ep =
-         new ServerBrowserEndpoint(this, browserID,
-                                   (PagingFilteredQueue)binding.getQueue(), selector);
+      ServerBrowserEndpoint ep = new ServerBrowserEndpoint(this, browserID, binding.queue, selector);
 
       // still need to synchronized since close() can come in on a different thread
       synchronized (browsers)
@@ -1561,7 +1550,7 @@
    /*
     * Holds a record of a delivery - we need to store the consumer id as well
     * hence this class
-    * We can't rely on the cancel being driven from the MessageCallbackHandler since
+    * We can't rely on the cancel being driven from the ClientConsumer since
     * the deliveries may have got lost in transit (ignored) since the consumer might have closed
     * when they were in transit.
     * In such a case we might otherwise end up with the consumer closing but not all it's deliveries being

Modified: trunk/src/main/org/jboss/jms/server/endpoint/advised/SessionAdvised.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/advised/SessionAdvised.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/endpoint/advised/SessionAdvised.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -82,10 +82,10 @@
    
    public ConsumerDelegate createConsumerDelegate(JBossDestination destination, String selector,
                                                   boolean noLocal, String subscriptionName,
-                                                  boolean connectionConsumer) throws JMSException
+                                                  boolean connectionConsumer, boolean autoFlowControl) throws JMSException
    {
       return endpoint.createConsumerDelegate(destination, selector, noLocal, subscriptionName,
-                                             connectionConsumer);
+                                             connectionConsumer, autoFlowControl);
    }
    
    public BrowserDelegate createBrowserDelegate(JBossDestination queue, String messageSelector) throws JMSException                                                 

Modified: trunk/src/main/org/jboss/jms/server/messagecounter/MessageCounter.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/messagecounter/MessageCounter.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/messagecounter/MessageCounter.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -30,7 +30,7 @@
 import java.util.List;
 
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.Queue;
+import org.jboss.messaging.core.contract.Queue;
 
 /**
  * This class stores message count informations for a given queue

Modified: trunk/src/main/org/jboss/jms/server/messagecounter/MessageCounterManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/messagecounter/MessageCounterManager.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/messagecounter/MessageCounterManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -30,7 +30,7 @@
 import java.util.TimerTask;
 
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
+import org.jboss.messaging.core.contract.MessagingComponent;
 
 /**
  * 

Modified: trunk/src/main/org/jboss/jms/server/plugin/JDBCJMSUserManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/plugin/JDBCJMSUserManager.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/plugin/JDBCJMSUserManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -38,7 +38,7 @@
 
 import org.jboss.jms.server.plugin.contract.JMSUserManager;
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.plugin.JDBCSupport;
+import org.jboss.messaging.core.impl.JDBCSupport;
 
 /**
  * A JDBCJMSUserManager
@@ -164,44 +164,44 @@
 
       if (!populateTables.isEmpty())
       {         
-         Connection conn = null;      
-         TransactionWrapper tx = new TransactionWrapper();
+
+         Iterator iter = populateTables.iterator();
          
-         try
+         while (iter.hasNext())
          {
-            conn = ds.getConnection();
+            String statement = (String)iter.next();
             
-            Iterator iter = populateTables.iterator();
+            Statement st = null;
             
-            while (iter.hasNext())
+            Connection conn = null;         
+            
+            TransactionWrapper tx = null;
+                           
+            try
             {
-               String statement = (String)iter.next();
+               if (log.isTraceEnabled()) { log.trace("Executing: " + statement); }
                
-               Statement st = null;
+               tx = new TransactionWrapper();
                
-               try
-               {
-                  if (log.isTraceEnabled()) { log.trace("Executing: " + statement); }
-                  
-                  st = conn.createStatement();
-                  
-                  st.executeUpdate(statement);
-               }
-               catch (SQLException e) 
-               {
-                  log.debug("Failed to execute " + statement, e);
-               }
-               finally
-               {
-               	closeStatement(st);
-               }
-            }      
-         }
-         finally
-         {
-         	closeConnection(conn);
-            tx.end();
-         }    
+               conn = ds.getConnection();
+               
+               st = conn.createStatement();
+               
+               st.executeUpdate(statement);
+            }
+            catch (Exception e) 
+            {
+               log.debug("Failed to execute " + statement, e);
+               
+               tx.exceptionOccurred();
+            }
+            finally
+            {
+            	closeStatement(st);
+            	closeConnection(conn);
+            	tx.end();
+            }
+         }      
       }
    }
    

Modified: trunk/src/main/org/jboss/jms/server/plugin/JDBCJMSUserManagerService.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/plugin/JDBCJMSUserManagerService.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/plugin/JDBCJMSUserManagerService.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -24,8 +24,8 @@
 import javax.transaction.TransactionManager;
 
 import org.jboss.jms.server.plugin.contract.JMSUserManager;
-import org.jboss.messaging.core.plugin.JDBCServiceSupport;
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
+import org.jboss.messaging.core.contract.MessagingComponent;
+import org.jboss.messaging.core.jmx.JDBCServiceSupport;
 import org.jboss.messaging.util.ExceptionUtil;
 
 /**

Modified: trunk/src/main/org/jboss/jms/server/plugin/contract/JMSUserManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/plugin/contract/JMSUserManager.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/plugin/contract/JMSUserManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -21,7 +21,7 @@
  */
 package org.jboss.jms.server.plugin.contract;
 
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
+import org.jboss.messaging.core.contract.MessagingComponent;
 
 /**
  * A JMSUserManager

Modified: trunk/src/main/org/jboss/jms/server/selector/Selector.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/selector/Selector.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/selector/Selector.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -29,7 +29,7 @@
 import javax.jms.Message;
 
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.Filter;
+import org.jboss.messaging.core.contract.Filter;
 
 
 /**
@@ -114,7 +114,7 @@
       return selector;
    }
 	
-	public synchronized boolean accept(org.jboss.messaging.core.message.Message message)
+	public synchronized boolean accept(org.jboss.messaging.core.contract.Message message)
    {
       try
       {			         

Modified: trunk/src/main/org/jboss/jms/server/selector/SelectorFactory.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/selector/SelectorFactory.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/server/selector/SelectorFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -21,8 +21,8 @@
  */
 package org.jboss.jms.server.selector;
 
-import org.jboss.messaging.core.Filter;
-import org.jboss.messaging.core.FilterFactory;
+import org.jboss.messaging.core.contract.Filter;
+import org.jboss.messaging.core.contract.FilterFactory;
 
 /**
  * A SelectorFactory

Modified: trunk/src/main/org/jboss/jms/tx/ClientTransaction.java
===================================================================
--- trunk/src/main/org/jboss/jms/tx/ClientTransaction.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/tx/ClientTransaction.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -35,7 +35,7 @@
 import org.jboss.jms.delegate.DeliveryInfo;
 import org.jboss.jms.message.JBossMessage;
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.message.MessageFactory;
+import org.jboss.messaging.core.impl.message.MessageFactory;
 
 /**
  * Holds the state of a transaction on the client side
@@ -71,7 +71,10 @@
    private boolean hasPersistentAcks;
    
    private boolean failedOver;
+   
+   private boolean removeAcks;
 
+
    // Static --------------------------------------------------------
 
    // Constructors --------------------------------------------------
@@ -98,7 +101,7 @@
 
       sessionTxState.addMessage(msg);
    }
-
+   
    public void addAck(int sessionId, DeliveryInfo info)
    {
       if (!clientSide)
@@ -113,6 +116,11 @@
       {
          hasPersistentAcks = true;
       }
+      
+      if (!info.isShouldAck())
+      {
+      	removeAcks = true;
+      }
    }
    
    public boolean hasPersistentAcks()
@@ -124,7 +132,7 @@
    {
       return failedOver;
    }
-
+   
    public void clearMessages()
    {
       if (!clientSide)
@@ -236,6 +244,45 @@
    }
 
    // Streamable implementation ---------------------------------
+   
+   //For message consumed using a non durable subscriber - we don't need to ack to the server
+   //so we remove them here
+   //TODO this could be optimised to prevent this extra removal stage before sending
+   public void removeUnnecessaryAcks()
+   {
+   	if (removeAcks)
+   	{
+	   	Iterator iter = sessionStatesMap.values().iterator();
+	
+	      while (iter.hasNext())
+	      {
+	         SessionTxState state = (SessionTxState)iter.next();
+	
+	         List acks = state.getAcks();
+	
+	         Iterator iter2 = acks.iterator();
+	         
+	         List newAcks = new ArrayList();
+	
+	         while (iter2.hasNext())
+	         {
+	            DeliveryInfo ack = (DeliveryInfo)iter2.next();
+	
+	            if (ack.isShouldAck())
+	            {
+	            	if (newAcks == null)
+	            	{
+	            		newAcks = new ArrayList();
+	            	}
+	            	newAcks.add(ack);
+	            }
+	         }
+	         
+	         state.setAcks(newAcks);
+	      }
+   	}
+   }
+   
 
    public void write(DataOutputStream out) throws Exception
    {
@@ -401,6 +448,11 @@
       {
          return sessionID;
       }
+      
+      public void setAcks(List acks)
+      {
+      	this.acks = acks;
+      }
 
       void handleFailover(int newServerID, int oldSessionID, int newSessionID)
       {

Modified: trunk/src/main/org/jboss/jms/tx/ResourceManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/tx/ResourceManager.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/tx/ResourceManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -205,6 +205,8 @@
       
       try
       {
+      	request.state.removeUnnecessaryAcks();
+      	
          connection.sendTransaction(request, false);
          
          // If we get this far we can remove the transaction
@@ -632,6 +634,11 @@
    {
       try
       {
+      	if (request.state != null)
+      	{
+      		request.state.removeUnnecessaryAcks();
+      	}
+      	
          connection.sendTransaction(request, false);
       }
       catch (Throwable t)

Modified: trunk/src/main/org/jboss/jms/wireformat/BrowserNextMessageBlockResponse.java
===================================================================
--- trunk/src/main/org/jboss/jms/wireformat/BrowserNextMessageBlockResponse.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/wireformat/BrowserNextMessageBlockResponse.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -25,7 +25,7 @@
 import java.io.DataOutputStream;
 
 import org.jboss.jms.message.JBossMessage;
-import org.jboss.messaging.core.message.MessageFactory;
+import org.jboss.messaging.core.impl.message.MessageFactory;
 
 /**
  * 

Modified: trunk/src/main/org/jboss/jms/wireformat/BrowserNextMessageResponse.java
===================================================================
--- trunk/src/main/org/jboss/jms/wireformat/BrowserNextMessageResponse.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/wireformat/BrowserNextMessageResponse.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -25,7 +25,7 @@
 import java.io.DataOutputStream;
 
 import org.jboss.jms.message.JBossMessage;
-import org.jboss.messaging.core.message.MessageFactory;
+import org.jboss.messaging.core.impl.message.MessageFactory;
 
 /**
  * 

Modified: trunk/src/main/org/jboss/jms/wireformat/ClientDelivery.java
===================================================================
--- trunk/src/main/org/jboss/jms/wireformat/ClientDelivery.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/wireformat/ClientDelivery.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -24,8 +24,8 @@
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageFactory;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.impl.message.MessageFactory;
 
 /**
  * 

Modified: trunk/src/main/org/jboss/jms/wireformat/SessionCreateConsumerDelegateRequest.java
===================================================================
--- trunk/src/main/org/jboss/jms/wireformat/SessionCreateConsumerDelegateRequest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/wireformat/SessionCreateConsumerDelegateRequest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -47,6 +47,7 @@
    private boolean noLocal;
    private String subName;
    private boolean connectionConsumer;
+   private boolean autoFlowControl;
 
    public SessionCreateConsumerDelegateRequest()
    {      
@@ -56,7 +57,8 @@
                                                byte version,
                                                JBossDestination destination,
                                                String selector, boolean noLocal,
-                                               String subName, boolean connectionConsumer)
+                                               String subName, boolean connectionConsumer,
+                                               boolean autoFlowControl)
    {
       super(objectId, PacketSupport.REQ_SESSION_CREATECONSUMERDELEGATE, version);
       
@@ -65,6 +67,7 @@
       this.noLocal = noLocal;
       this.subName = subName;
       this.connectionConsumer = connectionConsumer;
+      this.autoFlowControl = autoFlowControl;
    }
 
    public void read(DataInputStream is) throws Exception
@@ -80,6 +83,8 @@
       subName = readNullableString(is);
       
       connectionConsumer = is.readBoolean();
+      
+      autoFlowControl = is.readBoolean();
    }
 
    public ResponseSupport serverInvoke() throws Exception
@@ -92,7 +97,7 @@
          throw new IllegalStateException("Cannot find object in dispatcher with id " + objectId);
       }
       
-      return new SessionCreateConsumerDelegateResponse((ClientConsumerDelegate)endpoint.createConsumerDelegate(dest, selector, noLocal, subName, connectionConsumer));
+      return new SessionCreateConsumerDelegateResponse((ClientConsumerDelegate)endpoint.createConsumerDelegate(dest, selector, noLocal, subName, connectionConsumer, autoFlowControl));
    }
 
    public void write(DataOutputStream os) throws Exception
@@ -109,6 +114,8 @@
       
       os.writeBoolean(connectionConsumer);
       
+      os.writeBoolean(autoFlowControl);
+      
       os.flush();
    }
 

Modified: trunk/src/main/org/jboss/jms/wireformat/SessionSendRequest.java
===================================================================
--- trunk/src/main/org/jboss/jms/wireformat/SessionSendRequest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/jms/wireformat/SessionSendRequest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -27,7 +27,7 @@
 
 import org.jboss.jms.delegate.SessionEndpoint;
 import org.jboss.jms.message.JBossMessage;
-import org.jboss.messaging.core.message.MessageFactory;
+import org.jboss.messaging.core.impl.message.MessageFactory;
 
 /**
  * 

Deleted: trunk/src/main/org/jboss/messaging/core/Channel.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/Channel.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/Channel.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,150 +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.util.List;
-
-/**
- * A Channel is a transactional, reliable message delivery mechanism that forwards a message from a
- * sender to one or more receivers.
- *
- * The channel tries to deliver a message synchronously, if possible, and stores the message for
- * re-delivery if synchronous delivery is not possible.
- *
- * A channel implementation may chose to be transactional, reliable or none of the above. A simple
- * channel implementation may not able to accept messages/acknowledgments transactionally, and may
- * not guarantee recoverability in case of failure. A <i>transactional</i> channel must be able to
- * guarantee atomicity when accepting messages/acknowledgments. A <i>reliable</i> channel must be
- * able to guarantee atomicity and recoverability in case of failure. However, recoverability is
- * guaranteed only for reliable messages. For non-reliable message, the channel will do its best
- * effort.
- *
- * @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 Channel extends DeliveryObserver, Distributor, Receiver
-{
-   /**    
-    * @return the unique ID of the channel
-    */
-   long getChannelID();
-
-   /**
-    * @return true if the channel can guarantee recoverability for <i>reliable</i> messages.
-    *         Recoverability is not guaranteed for non-reliable messages (and <i>should not</i>
-    *         be provided by default, for performance reasons), even if the channel is recoverable.
-    */
-   boolean isRecoverable();
-
-   /**
-    * A non-recoverable channel cannot guarantee recoverability for reliable messages so by default
-    * it won't accept reliable messages. However, there are situations when discarding a reliable
-    * message is acceptable for a specific instance of a channel, so it should be a way to
-    * configure the channel to do so.
-    *
-    * A channel indicates unequivocally whether it accepts reliable messages or not returning
-    * true or false as result of this method.
-    *
-    * A recoverable channel must always accept reliable messages, so this method must always return
-    * true for a recoverable channel.
-    *
-    * @return false if the channel doesn't accept reliable messages.
-    */
-   public boolean acceptReliableMessages();
-
-   /**
-    * @return a List containing messages being held by the channel. 
-    */
-   List browse();
-
-   /**
-    * @param filter - may be null, in which case no filter is applied.
-    *
-    * @return a List containing message references of messages whose state is maintained by this
-    *         State instance. 
-    */
-   List browse(Filter filter);
-
-   /**
-    * Delivers as many references as possible to its router until no more deliveries are returned.
-    */
-   void deliver();
-
-   /**
-    * Close the channel
-    *
-    */
-   void close();
-
-   /**
-    * Clears non-recoverable state but not persisted state, so a recovery of the channel is possible
-    * TODO really?
-    */
-   void clear();
-   
-   /**
-    * 
-    * @return Total message count = undelivered + delivering + scheduled
-    */
-   int getMessageCount();
-   
-   /**
-    * 
-    * @return Count being delivered
-    */
-   int getDeliveringCount();
-   
-   /**
-    * Count scheduled for delivery
-    */
-   int getScheduledCount();
-   
-   /**
-    * Remove all the references in the channel
-    * @throws Throwable
-    */
-   void removeAllReferences() throws Throwable;
-   
-   void load() throws Exception;
-   
-   void unload() throws Exception;
-   
-   void activate();
-   
-   void deactivate();
-   
-   boolean isActive();
-   
-   List recoverDeliveries(List messageIds);
-  
-   int getMaxSize();
-   
-   void setMaxSize(int newSize);
-   
-   //Count of messages added since server was started (needed for stats)
-   int getMessagesAdded();
-}
-
-

Deleted: trunk/src/main/org/jboss/messaging/core/ChannelSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/ChannelSupport.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/ChannelSupport.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,1141 +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.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Set;
-
-import org.jboss.jms.server.MessagingTimeoutFactory;
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.message.MessageReference;
-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.TransactionException;
-import org.jboss.messaging.core.tx.TxCallback;
-import org.jboss.messaging.util.prioritylinkedlist.BasicPriorityLinkedList;
-import org.jboss.messaging.util.prioritylinkedlist.PriorityLinkedList;
-import org.jboss.util.timeout.Timeout;
-import org.jboss.util.timeout.TimeoutTarget;
-
-import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt;
-
-/**
- * 
- * This class provides much of the functionality needed to implement a channel.
- * 
- * This partial implementation supports atomicity, isolation and recoverability of 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: ChannelSupport.java,v 1.65
- *          2006/06/27 19:44:39 timfox Exp $
- */
-public abstract class ChannelSupport implements Channel
-{
-   // Constants ------------------------------------------------------------------------------------
-
-   private static final Logger log = Logger.getLogger(ChannelSupport.class);
-
-   // Static ---------------------------------------------------------------------------------------
-
-   // Attributes -----------------------------------------------------------------------------------
-
-   private boolean trace = log.isTraceEnabled();
-
-   protected long channelID;
-
-   protected Router router;
-
-   protected MessageStore ms;
-
-   protected boolean receiversReady;
-
-   protected PriorityLinkedList messageRefs;
-
-   protected boolean acceptReliableMessages;
-
-   protected boolean recoverable;
-
-   protected PersistenceManager pm;
-
-   protected Object lock;
-
-   protected boolean active = true;
-   
-   //TODO - I would like to get rid of this - the only reason we still keep a count of
-   //refs being delivered is because many tests require this
-   //Having to keep this count requires synchronization between delivery thread and acknowledgement
-   //thread which will hamper concurrency
-   //Suggest that we have a flag that disables this for production systems
-   protected SynchronizedInt deliveringCount;
-    
-   protected Set scheduledDeliveries;
-   
-   //The maximum number of refs this queue can hold, or -1 if no limit
-   //If any more refs are added after this point they are dropped
-   protected int maxSize;
-  
-   protected SynchronizedInt messagesAdded;
-    
-   // Constructors ---------------------------------------------------------------------------------
-
-   protected ChannelSupport(long channelID, MessageStore ms,
-                            PersistenceManager pm,
-                            boolean acceptReliableMessages, boolean recoverable,
-                            int maxSize)
-   {
-      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");
-      }
-      
-      if (pm == null)
-      {
-         throw new IllegalArgumentException("ChannelSupport requires a " +
-                                            "non-null persistence manager");
-      }
-
-      this.ms = ms;
-
-      this.pm = pm;
-
-      this.channelID = channelID;
-
-      this.acceptReliableMessages = acceptReliableMessages;
-
-      this.recoverable = recoverable;
-
-      messageRefs = new BasicPriorityLinkedList(10);
-
-      lock = new Object();
-      
-      deliveringCount = new SynchronizedInt(0);
-      
-      scheduledDeliveries = new HashSet();
-      
-      this.maxSize = maxSize;
-      
-      this.messagesAdded = new SynchronizedInt(0);
-   }
-
-   // Receiver implementation ----------------------------------------------------------------------
-
-   public Delivery handle(DeliveryObserver sender, MessageReference ref, Transaction tx)
-   {
-      if (!isActive())
-      {
-         return null;
-      }
-
-      checkClosed();
-
-      return handleInternal(sender, ref, tx, true);      
-   }
-
-   // DeliveryObserver implementation --------------------------------------------------------------
-
-   public void acknowledge(Delivery d, Transaction tx) throws Throwable
-   {
-      if (trace) { log.trace("acknowledging " + d + (tx == null ? " non-transactionally" : " transactionally in " + tx)); }
-
-      acknowledgeInternal(d, tx, true);
-   }
-
-   public void cancel(Delivery del) throws Throwable
-   {
-      //We may need to update the delivery count in the database
-      
-      MessageReference ref = del.getReference();
-      
-      if (ref.getMessage().isReliable())
-      {
-         pm.updateDeliveryCount(this.channelID, ref);
-      }
-            
-      deliveringCount.decrement();
-
-      if (!checkAndSchedule(ref))
-      {
-         cancelInternal(ref);
-      }
-   }      
-        
-   // Distributor implementation -------------------------------------------------------------------
-
-   public boolean add(Receiver r)
-   {
-      if (trace) { log.trace(this + " attempting to add receiver " + r); }
-      
-      synchronized (lock)
-      {	
-	      boolean added = router.add(r);
-	
-	      if (trace) { log.trace("receiver " + r + (added ? "" : " NOT") + " added"); }
-	
-	      receiversReady = true;
-	      
-	
-	      return added;
-      }
-   }
-
-   public boolean remove(Receiver r)
-   {
-   	synchronized (lock)
-   	{	   	
-	      boolean removed = router.remove(r);
-	
-	      if (removed && !router.iterator().hasNext())
-	      {
-	         receiversReady = false;	         
-	      }
-	
-	      if (trace) { log.trace(this + (removed ? " removed " : " did NOT remove ") + r); }
-	
-	      return removed;
-   	}
-   }
-
-   public void clear()
-   {
-      synchronized (lock)
-      {
-         router.clear();         
-      	
-         receiversReady = false;
-      }
-   }
-
-   public boolean contains(Receiver r)
-   {
-      synchronized (lock)
-      {
-      	return router.contains(r);
-      }
-   }
-
-   public Iterator iterator()
-   {
-   	synchronized (lock)
-   	{
-   		return router.iterator();
-   	}
-   }
-
-   public int getNumberOfReceivers()
-   {
-   	synchronized (lock)
-   	{
-   		return router.getNumberOfReceivers();
-   	}
-   }
-
-   // Channel implementation -----------------------------------------------------------------------
-
-   public long getChannelID()
-   {
-      return channelID;
-   }
-
-   public boolean isRecoverable()
-   {
-      return recoverable;
-   }
-
-   public boolean acceptReliableMessages()
-   {
-      return acceptReliableMessages;
-   }
-
-   public List browse()
-   {
-      return browse(null);
-   }
-
-   public List browse(Filter filter)
-   {
-      if (trace) { log.trace(this + " browse" + (filter == null ? "" : ", filter = " + filter)); }
-
-      synchronized (lock)
-      {
-         //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 = undelivered(filter);
-
-         // dereference pass
-         ArrayList messages = new ArrayList(references.size());
-         for (Iterator i = references.iterator(); i.hasNext();)
-         {
-            MessageReference ref = (MessageReference) i.next();
-            messages.add(ref.getMessage());
-         }
-         return messages;
-      }      
-   }
- 
-   public void deliver()
-   {
-      checkClosed();
-      
-      synchronized (lock)
-      {      
-	      if (router != null && router.getNumberOfReceivers() > 0)
-	      {                
-	         receiversReady = true;
-	            
-	         deliverInternal();                  
-	      }
-      }     
-   }      
-
-   public void close()
-   {
-   	synchronized (lock)
-   	{
-	      if (router != null)
-	      {
-	         router.clear();
-	         
-	         router = null;
-	      }
-	      
-	      clearAllScheduledDeliveries();
-   	}
-   }
-
-   /*
-    * This method clears the channel.
-    * Basically it consumes the rest of the messages in the channel.
-    * We can't just delete the corresponding references directly from the database since
-    * a) We might be paging
-    * b) The message might remain in the message store causing a leak
-    *
-    */
-   public void removeAllReferences() throws Throwable
-   {
-      log.debug(this + " removing all references");
-      
-      synchronized (lock)
-      {
-         if (deliveringCount.get() > 0)
-         {
-            throw new IllegalStateException("Cannot remove references while deliveries are in progress, there are " +
-            		deliveringCount.get());
-         }
-         
-         //Now we consume the rest of the messages
-         //This may take a while if we have a lot of messages including perhaps millions
-         //paged in the database - but there's no obvious other way to do it.
-         //We cannot just delete them directly from the database - because we may end up with messages leaking
-         //in the message store,
-         //also we might get race conditions when other channels are updating the same message in the db
-
-         //Note - we don't do this in a tx - because the tx could be too big if we have millions of refs
-         //paged in storage
-
-         MessageReference ref;
-         while ((ref = removeFirstInMemory()) != null)
-         {
-            SimpleDelivery del = new SimpleDelivery(this, ref);
-
-            del.acknowledge(null);
-
-            // Delivery#acknowledge decrements the deliveringCount without incrementing it first (because
-            // deliver has actually never been called), so increment it here to be accurate.  
-            deliveringCount.increment();
-         }
-      }
-      
-      clearAllScheduledDeliveries();
-   }
-
-   public List undelivered(Filter filter)
-   {
-      List undelivered = new ArrayList();
-
-      synchronized (lock)
-      {
-         Iterator iter = messageRefs.getAll().iterator();
-
-         while (iter.hasNext())
-         {
-            MessageReference r = (MessageReference) iter.next();
-
-            // TODO: I need to dereference the message each time I apply the
-            // filter. Refactor so the message reference will also contain JMS
-            // properties
-            if (filter == null || filter.accept(r.getMessage()))
-            {
-               undelivered.add(r);
-            }
-            else
-            {
-               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"); }
-
-      return undelivered;
-   }
-
-   /**
-    * Returns the count of messages stored AND being delivered AND scheduled
-    */
-   public int getMessageCount()
-   {
-      synchronized (lock)
-      {
-         return messageRefs.size() + getDeliveringCount() + getScheduledCount();
-      }
-   }
-   
-   public int getDeliveringCount()
-   {
-      return deliveringCount.get();
-   }
-   
-   public int getScheduledCount()
-   {
-      synchronized (scheduledDeliveries)
-      {
-         return scheduledDeliveries.size();
-      }
-   }
-
-   public void activate()
-   {
-      synchronized (lock)
-      {
-         active = true;         
-      }
-   }
-
-   public void deactivate()
-   {
-      synchronized (lock)
-      {
-         active = false;         
-      }
-   }
-
-   public boolean isActive()
-   {
-      synchronized (lock)
-      {
-         return active;         
-      }
-   }
-   
-   public List recoverDeliveries(List messageIds)
-   {
-      //debug
-      Iterator iter = messageIds.iterator();
-                  
-      List dels = new ArrayList();
-      
-      synchronized (lock)
-      {
-         ListIterator liter = messageRefs.iterator();
-                           
-         while (iter.hasNext())
-         {
-            Long id = (Long)iter.next();
-            
-            //Scan the queue
-            while (true)
-            {               
-               if (!liter.hasNext())
-               {
-                  // TODO we need to look in paging state too - currently not supported
-                  //http://jira.jboss.com/jira/browse/JBMESSAGING-839
-                  log.warn(this + " cannot find reference " + id + " (Might be paged!)");
-                  break;
-               }
-               
-               MessageReference ref = (MessageReference)liter.next();
-               
-               if (ref.getMessage().getMessageID() == id.longValue())
-               {
-                  liter.remove();
-                  
-                  Delivery del = new SimpleDelivery(this, ref);
-                  
-                  dels.add(del);
-                                 
-                  break;
-               }
-            }
-         }           
-      }
-            
-      return dels;
-   }
-   
-   public int getMaxSize()
-   {
-      synchronized (lock)
-      {
-         return maxSize;
-      }
-   }
-   
-   public void setMaxSize(int newSize)
-   {
-      synchronized (lock)
-      {
-         int count = getMessageCount();
-         
-         if (newSize != -1 && count > newSize)
-         {
-            log.warn("Cannot set maxSize to " + newSize + " since there are already " + count + " refs");
-         }
-         else
-         {
-            maxSize = newSize;
-         }
-      }
-   }
-   
-   public int getMessagesAdded()
-   {
-      return messagesAdded.get();
-   }
-
-   // Public ---------------------------------------------------------------------------------------
-
-   //Only used for testing
-   public int memoryRefCount()
-   {
-      synchronized (lock)
-      {
-         return messageRefs.size();
-      }
-   }
-
-   //Only used for testing
-
-   public String toString()
-   {
-      return "ChannelSupport[" + channelID + "]";
-   }
-
-   // Package protected ----------------------------------------------------------------------------
-   
-   // Protected ------------------------------------------------------------------------------------
-   
-   protected void clearAllScheduledDeliveries()
-   {
-      synchronized (scheduledDeliveries)
-      {
-         Set clone = new HashSet(scheduledDeliveries);
-         
-         Iterator iter = clone.iterator();
-         
-         while (iter.hasNext())
-         {
-            Timeout timeout = (Timeout)iter.next();
-            
-            timeout.cancel();
-         }
-         
-         scheduledDeliveries.clear();
-      }
-   }
-
-   protected void cancelInternal(MessageReference ref) throws Exception
-   {
-      if (trace) { log.trace(this + " cancelling " + ref + " in memory"); }
-
-      synchronized (lock)
-      {
-         messageRefs.addFirst(ref, ref.getMessage().getPriority());
-      }
-                  
-      if (trace) { log.trace(this + " added " + ref + " back into state"); }
-   }
-   
-   /**
-    * This methods delivers as many messages as possible to the router until no more deliveries are
-    * returned. This method should never be called at the same time as handle.
-    *
-    * @see org.jboss.messaging.core.Channel#deliver()
-    */
-   protected void deliverInternal()
-   {
-      if (trace) { log.trace(this + " was prompted delivery"); }
-
-      try
-      {
-         // The iterator is used to iterate through the refs in the channel in the case that they
-         // don't match the selectors of any receivers.
-         ListIterator iter = null;
-         
-         MessageReference ref = null;
-         
-         if (!receiversReady)
-         {
-            return;
-         }
-         
-         while (true)
-         {           
-            ref = nextReference(iter);               
-                     
-            if (ref != null)
-            {
-               // Attempt to push the ref to a receiver
-               
-               if (trace) { log.trace(this + " pushing " + ref); }                                  
-
-               Delivery del = router.handle(this, ref, null);
-
-               receiversReady = del != null;
-               
-               if (del == null)
-               {
-                  // No receiver, broken receiver or full receiver so we stop delivering
-                  if (trace) { log.trace(this + " got no delivery for " + ref + " so no receiver got the message. Stopping delivery."); }
-                  
-                  break;
-               }
-               else if (!del.isSelectorAccepted())
-               {
-                  // No receiver accepted the message because no selectors matched, so we create
-                  // an iterator (if we haven't already created it) to iterate through the refs
-                  // in the channel. No delivery was really performed
-                  
-                  if (iter == null)
-                  {
-                     iter = messageRefs.iterator();
-                  }                     
-               }
-               else
-               {
-                  if (trace) { log.trace(this + ": " + del + " returned for message " + ref); }
-                  
-                  // Receiver accepted the reference
-                  
-                  synchronized (lock)
-                  {
-                     if (iter == null)
-                     {
-                        if (trace) { log.trace(this + " removing first ref in memory"); } 
-                        
-                        removeFirstInMemory();
-                     }
-                     else
-                     {
-                        if (trace) { log.trace(this + " removed current message from iterator"); }                           
-                                    
-                        iter.remove();                                
-                     }
-                  }
-                                  
-                  deliveringCount.increment();                     
-               }               
-            }
-            else
-            {
-               // No more refs in channel or only ones that don't match any selectors
-               if (trace) { log.trace(this + " no more refs to deliver "); }
-               
-               break;
-            }            
-         }         
-      }
-      catch (Throwable t)
-      {
-         log.error(this + " Failed to deliver", t);
-      }
-   }
-   
-   protected boolean deliverScheduled(MessageReference ref)
-   {
-      try
-      {      
-         // We synchonize on the ref lock to prevent scheduled deivery kicking in before
-         // load has finished
-         synchronized (lock)
-         {
-            // Attempt to push the ref to a receiver
-            
-            if (trace) { log.trace(this + " pushing " + ref); }                                  
-   
-            Delivery del = router.handle(this, ref, null);
-   
-            receiversReady = del != null;
-            
-            if (del == null)
-            {
-               // No receiver, broken receiver or full receiver so we stop delivering
-               if (trace) { log.trace(this + ": no delivery returned for message" + ref + " so no receiver got the message. Delivery is now complete"); }
-   
-               return false;
-            }
-            else if (del.isSelectorAccepted())
-            {
-               if (trace) { log.trace(this + ": " + del + " returned for message:" + ref); }
-               
-               // Receiver accepted the reference
-               
-               deliveringCount.increment();                   
-               
-               return true;
-            }                
-         }
-      }
-      catch (Throwable t)
-      {
-         log.error(this + " Failed to deliver", t);
-      }
-      
-      return false;
-   }
-      
-   protected Delivery handleInternal(DeliveryObserver sender, MessageReference ref,
-                                     Transaction tx, boolean persist)
-   {
-      if (ref == null)
-      {
-         return null;
-      }
-
-      if (trace) { log.trace(this + " handles " + ref + (tx == null ? " non-transactionally" : " in transaction: " + tx)); }
-      
-      if (maxSize != -1 && getMessageCount() >= maxSize)
-      {
-         //Have reached maximum size - will drop message
-         
-         log.warn(this + " has reached maximum size, " + ref + " will be dropped");
-         
-         return null;
-      }
-   
-      // Each channel has its own copy of the reference
-      ref = ref.copy();
-
-      try
-      {  
-         if (tx == null)
-         {
-            // Don't even attempt synchronous delivery for a reliable message when we have an
-            // non-recoverable state that doesn't accept reliable messages. If we do, we may get
-            // into the situation where we need to reliably store an active delivery of a reliable
-            // message, which in these conditions cannot be done.
-
-            if (ref.getMessage().isReliable() && !acceptReliableMessages)
-            {
-               log.error("Cannot handle reliable message " + ref +
-                  " because the channel has a non-recoverable state!");
-               return null;
-            }
-        
-            if (persist && ref.getMessage().isReliable() && recoverable)
-            {
-               // Reliable message in a recoverable state - also add to db
-               if (trace) { log.trace(this + " adding " + ref + " to database non-transactionally"); }
-
-               // TODO - this db access could safely be done outside the event loop
-               pm.addReference(channelID, ref, null);        
-            }
-            
-            // If the ref has a scheduled delivery time then we don't add to the in memory queue
-            // instead we create a timeout, so when that time comes delivery will attempted directly
-            
-            if (!checkAndSchedule(ref))
-            {               
-               synchronized (lock)
-               {
-                  addReferenceInMemory(ref);
-                  
-                  deliverInternal();
-               }            
-            }
-         }
-         else
-         {
-            if (trace) { log.trace(this + " adding " + ref + " to state " + (tx == null ? "non-transactionally" : "in transaction: " + tx)); }
-
-            if (ref.getMessage().isReliable() && !acceptReliableMessages)
-            {
-               // this transaction has no chance to succeed, since a reliable
-               // message cannot be
-               // safely stored by a non-recoverable state, so doom the
-               // transaction               
-               log.warn(this + " cannot handle reliable messages, dooming the transaction");
-               
-               tx.setRollbackOnly();
-            } 
-            else
-            {
-               // add to post commit callback
-               getCallback(tx).addRef(ref);
-               
-               if (trace) { log.trace(this + " added transactionally " + ref + " in memory"); }
-            }
-
-            if (persist && ref.getMessage().isReliable() && recoverable)
-            {
-               // Reliable message in a recoverable state - also add to db
-               if (trace) { log.trace(this + " adding " + ref + (tx == null ? " to database non-transactionally" : " in transaction: " + tx)); }
-
-               pm.addReference(channelID, ref, tx);
-            }
-         }
-         
-         messagesAdded.increment();
-      }
-      catch (Throwable t)
-      {
-         log.error("Failed to handle message", t);
-
-         ref.releaseMemoryReference();
-
-         return null;
-      }
-
-      return new SimpleDelivery(this, ref, true);
-   }
-
-   
-   protected boolean checkAndSchedule(MessageReference ref)
-   {
-      if (ref.getScheduledDeliveryTime() > System.currentTimeMillis())
-      {      
-         if (trace) { log.trace("Scheduling delivery for " + ref + " to occur at " + ref.getScheduledDeliveryTime()); }
-         
-         // Schedule the cancel to actually occur at the specified time. Need to synchronize to
-         // prevent timeout being removed before it is added.
-         synchronized (scheduledDeliveries)
-         {            
-            Timeout timeout =
-               MessagingTimeoutFactory.instance.getFactory().
-                  schedule(ref.getScheduledDeliveryTime(), new DeliverRefTimeoutTarget(ref));
-            
-            scheduledDeliveries.add(timeout);
-         }      
-         
-         return true;
-      }
-      else
-      {
-         return false;
-      }
-   }
-   
-   protected void acknowledgeInternal(Delivery d, Transaction tx, boolean persist) throws Exception
-   {   
-      if (tx == null)
-      {                  
-         if (persist && recoverable && d.getReference().getMessage().isReliable())
-         {
-            pm.removeReference(channelID, d.getReference(), null);
-         }
-              
-         d.getReference().releaseMemoryReference(); 
-                  
-         deliveringCount.decrement();
-      }
-      else
-      {
-         this.getCallback(tx).addDelivery(d);
-   
-         if (trace) { log.trace(this + " added " + d + " to memory on transaction " + tx); }
-   
-         if (recoverable && d.getReference().getMessage().isReliable())
-         {
-            pm.removeReference(channelID, d.getReference(), tx);
-         }
-      }
-   }
-
-   protected InMemoryCallback getCallback(Transaction tx)
-   {
-      InMemoryCallback callback = (InMemoryCallback) tx.getCallback(this);            
-
-      if (callback == null)
-      {
-         callback = new InMemoryCallback();
-
-         tx.addCallback(callback, this);
-      }
-
-      return callback;
-   }
- 
-   protected MessageReference removeFirstInMemory() throws Exception
-   {
-      MessageReference result = (MessageReference) messageRefs.removeFirst();
-
-      return (MessageReference) result;
-   }
-   
-   protected void addReferenceInMemory(MessageReference ref) throws Exception
-   {
-      if (ref.getMessage().isReliable() && !acceptReliableMessages)
-      {
-         throw new IllegalStateException("Reliable reference " + ref +
-                                         " cannot be added to non-recoverable state");
-      }
-
-      messageRefs.addLast(ref, ref.getMessage().getPriority());
-
-      if (trace){ log.trace(this + " added " + ref + " non-transactionally in memory"); }      
-   }    
-   
-   // Private --------------------------------------------------------------------------------------
-      
-   private MessageReference nextReference(ListIterator iter) throws Throwable
-   {
-      MessageReference ref;
-      
-      if (iter == null)
-      {
-         //We just get the next ref from the head of the queue
-         ref = (MessageReference) messageRefs.peekFirst();
-      }
-      else
-      {
-         // TODO This will not work with paged refs - see http://jira.jboss.com/jira/browse/JBMESSAGING-275
-         // We need to extend it to work with refs from the db
-         
-         //We have an iterator - this means we are iterating through the queue to find a ref that matches
-         if (iter.hasNext())
-         {                        
-            ref = (MessageReference)iter.next();
-         } 
-         else
-         {
-            ref = null;
-         }
-      }
-      
-      return ref;
-   } 
-
-   // Inner classes --------------------------------------------------------------------------------
-
-   private class InMemoryCallback implements TxCallback
-   {
-      private List refsToAdd;
-
-      private List deliveriesToRemove;
-      
-      private InMemoryCallback()
-      {
-         refsToAdd = new ArrayList();
-
-         deliveriesToRemove = new ArrayList();
-      }
-      
-      private void addRef(MessageReference ref)
-      {
-         refsToAdd.add(ref);
-      }
-
-      private void addDelivery(Delivery del)
-      {
-         deliveriesToRemove.add(del);
-      }
-
-      public void beforePrepare()
-      {
-         // NOOP
-      }
-
-      public void beforeCommit(boolean onePhase)
-      {
-         // NOOP
-      }
-
-      public void beforeRollback(boolean onePhase)
-      {
-         // NOOP
-      }
-
-      public void afterPrepare()
-      {
-         // NOOP
-      }
-      
-      public void afterCommit(boolean onePhase) throws Exception
-      {         
-         try
-         {
-            // We add the references to the state
-         	
-         	boolean promptDelivery = false;
-            
-            for(Iterator i = refsToAdd.iterator(); i.hasNext(); )
-            {
-               MessageReference ref = (MessageReference)i.next();
-
-               if (trace) { log.trace(this + ": adding " + ref + " to non-recoverable state"); }
-
-               try
-               {
-                  synchronized (lock)
-                  {
-                     addReferenceInMemory(ref);
-                  }
-               }
-               catch (Throwable t)
-               {
-                  throw new TransactionException("Failed to add reference", t);
-               }
-               
-               //Only need to prompt delivery if refs were added
-               promptDelivery = true;
-            }
-
-            // Remove deliveries
-            
-            for(Iterator i = deliveriesToRemove.iterator(); i.hasNext(); )
-            {
-               Delivery del = (Delivery)i.next();
-
-               if (trace) { log.trace(this + " removing " + del + " after commit"); }
-
-               del.getReference().releaseMemoryReference();
-               
-               deliveringCount.decrement();
-            }
-            
-            // prompt delivery
-            if (promptDelivery)
-            {
-            	synchronized (lock)
-            	{
-            		deliverInternal();
-            	}
-            }
-         }
-         catch (Throwable t)
-         {
-            log.error("failed to commit", t);
-            throw new Exception("Failed to commit", t);
-         }
-         
-      }
-
-      public void afterRollback(boolean onePhase) throws Exception
-      {
-         for(Iterator i = refsToAdd.iterator(); i.hasNext(); )
-         {
-            MessageReference ref = (MessageReference)i.next();
-
-            if (trace) { log.trace(this + " releasing memory " + ref + " after rollback"); }
-            ref.releaseMemoryReference();
-         }
-      }
-
-      public String toString()
-      {
-         return ChannelSupport.this + ".InMemoryCallback[" +
-                Integer.toHexString(InMemoryCallback.this.hashCode()) + "]";
-      }
-   }
-
-   /**
-    * Give subclass a chance to process the message before storing it internally.
-    * TODO - Do we really need this?
-    */
-   protected void processMessageBeforeStorage(MessageReference reference)
-   {
-      // by default a noop
-   }
-
-   protected void checkClosed()
-   {
-      if (router == null)
-      {
-         throw new IllegalStateException(this + " closed");
-      }
-   }
-
-   // Private --------------------------------------------------------------------------------------
-   
-   // Inner classes --------------------------------------------------------------------------------
-
-   private class DeliverRefTimeoutTarget implements TimeoutTarget
-   {
-      private MessageReference ref;
-
-      public DeliverRefTimeoutTarget(MessageReference ref)
-      {
-         this.ref = ref;
-      }
-
-      public void timedOut(Timeout timeout)
-      {
-         if (trace) { log.trace("Scheduled delivery timeout " + ref); }
-         
-         synchronized (scheduledDeliveries)
-         {
-            boolean removed = scheduledDeliveries.remove(timeout);
-            
-            if (!removed)
-            {
-               throw new IllegalStateException("Failed to remove timeout " + timeout);
-            }
-         }
-              
-         ref.setScheduledDeliveryTime(0);
-         
-         boolean delivered = false;
-         
-         if (router.getNumberOfReceivers() > 0)
-         {               
-            delivered = deliverScheduled(ref);     
-         }
-
-         if (!delivered)
-         {
-            try
-            {
-               cancelInternal(ref);
-            }
-            catch (Exception e)
-            {
-               log.error("Failed to cancel", e);
-            }
-         }
-         else
-         {
-            if (trace) { log.trace("Delivered scheduled delivery at " + System.currentTimeMillis() + " for " + ref); }
-         }
-      }
-   }
-}

Deleted: trunk/src/main/org/jboss/messaging/core/Delivery.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/Delivery.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/Delivery.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,55 +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.message.MessageReference;
-import org.jboss.messaging.core.tx.Transaction;
-
-/**
- * A message delivery. It can be "done" or active.
- * 
- * @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 Delivery
-{
-   MessageReference getReference();
-
-   boolean isDone();
-   
-   void setObserver(DeliveryObserver observer);
-
-   DeliveryObserver getObserver();
-
-   // TODO this doesn't actually belong in the delivery, the selector should be moved "inside"
-   //      the channel. See http://jira.jboss.org/jira/browse/JBMESSAGING-275
-
-   boolean isSelectorAccepted();
-   
-   void acknowledge(Transaction tx) throws Throwable;
-
-   void cancel() throws Throwable;
-   
-}

Deleted: trunk/src/main/org/jboss/messaging/core/DeliveryObserver.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/DeliveryObserver.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/DeliveryObserver.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,37 +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;
-
-/**
- * @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 DeliveryObserver
-{
-   void acknowledge(Delivery d, Transaction tx) throws Throwable;
-
-   void cancel(Delivery d) throws Throwable;
-}

Deleted: trunk/src/main/org/jboss/messaging/core/Distributor.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/Distributor.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/Distributor.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.messaging.core;
-
-import java.util.Iterator;
-
-/**
- * An interface for Receiver management.
- * 
- * Distributes a reference 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>
- * 
- * $Id$
- */
-public interface Distributor
-{
-
-   boolean contains(Receiver receiver);
-
-   /**
-    * @return an iterator of <i>local</i> receivers
-    */
-   Iterator iterator();
-
-   /**
-    * Add a local receiver to this distributor.
-    *
-    * @return true if the distributor did not already contain the specified receiver and the
-    *         receiver was added to the distributor, false otherwise.
-    */
-   boolean add(Receiver receiver);
-
-   /**
-    * Remove a local receiver from this distributor.
-    *
-    * @return true if this distributor contained the specified receiver.
-    */
-   boolean remove(Receiver receiver);
-
-   /**
-    * Remove all receivers.
-    */
-   void clear();
-   
-   /**
-    * 
-    * @return The number of receivers in the distributor
-    */
-   int getNumberOfReceivers();
-
-}

Deleted: trunk/src/main/org/jboss/messaging/core/Filter.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/Filter.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/Filter.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,46 +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.message.Message;
-
-/**
- * A filter encapsulates the logic of whether to accept a message or not. Filters are used when
- * browsing to restrict the messages browsed, or when routing messages.
- *
- * @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$</tt>
- *
- * $Id$
- */
-public interface Filter
-{
-	/**
-	 * Tests whether the message should be accepted.
-    *
-	 * @return true if the Filter accepts the message - i.e. let's it pass.
-	 */
-	boolean accept(Message message);
-   
-   String getFilterString();
-}

Deleted: trunk/src/main/org/jboss/messaging/core/FilterFactory.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/FilterFactory.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/FilterFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,40 +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;
-
-
-/**
- * A FilterFactory
- * 
- * This exists so we can abstract out the creation of filters inside core code so
- * we don't have dependencies on jms selectors
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public interface FilterFactory
-{
-   Filter createFilter(String filterString) throws Exception;
-}

Deleted: trunk/src/main/org/jboss/messaging/core/PagingChannelSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/PagingChannelSupport.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/PagingChannelSupport.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,609 +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.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.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-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;
-
-/**
- * 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$</tt>
- *
- * $Id$
- */
-public abstract class PagingChannelSupport extends ChannelSupport
-{
-   private static final Logger log = Logger.getLogger(PagingChannelSupport.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 = 200000;
-
-   /**
-    * The maximum number of references to load from storage in one go when unpaging
-    */
-   protected int pageSize = 2000;
-
-   /**
-    * The maximum number of references paged to storage in one operation
-    */
-   protected int downCacheSize = 2000;
-
-   /**
-    * 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;
-   
-   /**
-    * Constructor with default paging params.
-    */
-   public PagingChannelSupport(long channelID, MessageStore ms, PersistenceManager pm,
-                               boolean acceptReliableMessages, boolean recoverable,                        
-                               int maxSize)
-   {
-      super(channelID, ms, pm, acceptReliableMessages, recoverable, maxSize);
-      
-      downCache = new ArrayList(downCacheSize);    
-      
-      active = true;
-   }
-   
-   /**
-    * Constructor specifying paging params.
-    */
-   public PagingChannelSupport(long channelID, MessageStore ms, PersistenceManager pm,
-                               boolean acceptReliableMessages, boolean recoverable,                        
-                               int maxSize,
-                               int fullSize, int pageSize, int downCacheSize)
-   {
-      super(channelID, ms, pm, acceptReliableMessages, recoverable, maxSize);
-      
-      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;
-      
-      active = true;
-   }
-    
-   // Receiver implementation ----------------------------------------------------------------------
-
-   // Channel implementation -----------------------------------------------------------------------
-
-   public int getMessageCount()
-   {   
-      int count = super.getMessageCount();
-      
-      // Also need to add the paged refs
-      
-      synchronized (lock)
-      {      
-         count += nextPagingOrder - firstPagingOrder;
-      }
-      
-      return count;
-   }
-   
-   // Public ---------------------------------------------------------------------------------------
-
-   //Only used in testing
-   public int downCacheCount()
-   {
-      synchronized (lock)
-      {
-         return downCache.size();
-      }
-   }
-
-   //Only used in testing
-   public boolean isPaging()
-   {
-      synchronized (lock)
-      {
-         return paging;
-      }
-   }
-   
-   public void setPagingParams(int fullSize, int pageSize, int downCacheSize)
-   {
-      synchronized (lock)
-      { 
-         if (active)
-         {
-            throw new IllegalStateException("Cannot set paging params when active");
-         }
-         
-         this.fullSize = fullSize;
-         
-         this.pageSize = pageSize;
-         
-         this.downCacheSize = downCacheSize;         
-      }
-   }
-   
-   public void load() throws Exception
-   {            
-      synchronized (lock)
-      {
-         if (active)
-         {
-            throw new IllegalStateException("Cannot load channel when active");
-         }
-         
-         if (trace) { log.trace(this + " loading channel state"); }
-         
-         unload();
-         
-         //Load the unpaged references
-         InitialLoadInfo ili = pm.loadFromStart(channelID, fullSize);
-         
-         doLoad(ili);
-         
-         //Maybe we need to load some paged refs
-         
-         while (checkLoad()) {}
-      }
-   }
-   
-   
-   
-      
-   public void unload() throws Exception
-   {
-      synchronized (lock)
-      {
-         if (active)
-         {
-            throw new IllegalStateException("Cannot unload channel when active");
-         }
-         
-         messageRefs.clear();
-         
-         downCache.clear();
-         
-         paging = false;
-         
-         firstPagingOrder = nextPagingOrder = 0;  
-         
-         clearAllScheduledDeliveries();
-      }
-   }
-   
-   
-   // Protected ------------------------------------------------------------------------------------
-   
-   protected void loadPagedReferences(int 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();
-      
-      int unreliableNumber = 0;
-
-      Iterator iter = refInfos.iterator();
-      while (iter.hasNext())
-      {
-         ReferenceInfo info = (ReferenceInfo)iter.next();
-         
-         MessageReference ref = addFromRefInfo(info, refMap);
-         
-         if (recoverable && ref.getMessage().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);
-            
-            unreliableNumber++;
-         }
-      }
-      
-      if (!toRemove.isEmpty())
-      {
-         // Now we remove the references we loaded (only the non persistent or persistent in a non-recoverable store)
-         
-         pm.removeDepagedReferences(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.updateReferencesNotPagedInRange(channelID, firstPagingOrder, firstPagingOrder + number - 1, number - unreliableNumber);
-      }
-            
-      firstPagingOrder += number;
-      
-      if (firstPagingOrder == nextPagingOrder)
-      {
-         //No more refs in storage
-         firstPagingOrder = nextPagingOrder = 0;
-         
-         if (messageRefs.size() != fullSize)
-         {
-            paging = false;
-         }
-      }    
-   }
-      
-   protected void cancelInternal(MessageReference ref) throws Exception
-   {
-      synchronized (lock)
-      {         
-         super.cancelInternal(ref);
-         
-         if (paging)
-         {
-            // if paging and the in memory queue is exactly full we need to evict the end reference to storage to
-            // preserve the number of refs in the queue
-            if (messageRefs.size() == fullSize + 1)
-            {
-               MessageReference refCancel = (MessageReference)messageRefs.removeLast();
-    
-               addToDownCache(refCancel, true);
-            }
-         }
-               
-         if (trace) { log.trace(this + " added " + ref + " back into state"); }      
-      }
-   }
-      
-   protected MessageReference removeFirstInMemory() throws Exception
-   {
-      MessageReference result = super.removeFirstInMemory();
-
-      checkLoad();
-
-      return result;
-   }
-   
-   private boolean checkLoad() throws Exception
-   {
-      long refNum = nextPagingOrder - firstPagingOrder;
-      
-      if (refNum > 0)
-      {
-         int numberLoadable = (int)Math.min(refNum, pageSize);
-         
-         if (messageRefs.size() <= fullSize - numberLoadable)
-         {
-            //This will flush the down cache too
-            loadPagedReferences(numberLoadable);
-            
-            return true;
-         }
-         else
-         {
-            return false;
-         }
-      }
-      else
-      {
-         paging = false;
-         
-         return false;
-      }
-   }
-    
-   protected void addReferenceInMemory(MessageReference ref) throws Exception
-   {     
-      if (paging)
-      {
-         if (ref.getMessage().isReliable() && !acceptReliableMessages)
-         {
-            throw new IllegalStateException("Reliable reference " + ref +
-                                            " cannot be added to non-recoverable state");
-         }
-         addToDownCache(ref, false);
-      }
-      else
-      {
-         super.addReferenceInMemory(ref);
-         
-         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, boolean cancelling) 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
-
-      //If cancelling then the ref is supposed to go back on the front of the queue segment in storage
-      //so we set the page ordering to be firstPageOrdering - 1
-      //If not cancelling, then the ref should go on the end of the queue in storage so
-      //we set the page ordering to be nextPageOrdering
-      
-      if (cancelling)
-      {
-         ref.setPagingOrder(firstPagingOrder - 1);
-         
-         firstPagingOrder--;
-      }
-      else
-      {
-         ref.setPagingOrder(nextPagingOrder);
-         
-         nextPagingOrder++;
-      }
-      
-      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();
-      
-      while (iter.hasNext())
-      {
-         MessageReference ref = (MessageReference) iter.next();
-           
-         if (ref.getMessage().isReliable() && recoverable)
-         {
-            toUpdate.add(ref);
-         }
-         else
-         {
-            toAdd.add(ref);
-         }
-      }
-      
-      if (!toAdd.isEmpty())
-      {
-         pm.pageReferences(channelID, toAdd, true);
-      }
-      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 (trace) { log.trace(this + " cleared downcache"); }
-   }
-   
-
-   
-   protected void doLoad(InitialLoadInfo ili) throws Exception
-   {
-      if (ili.getMaxPageOrdering() != null)            
-      {
-         firstPagingOrder = ili.getMinPageOrdering().longValue();
-         
-         nextPagingOrder = ili.getMaxPageOrdering().longValue() + 1;
-                           
-         paging = true;
-      }
-      else
-      {
-         firstPagingOrder = nextPagingOrder = 0;
-         
-         paging = false;
-      }
-      
-      Map refMap = processReferences(ili.getRefInfos());
-      
-      Iterator iter = ili.getRefInfos().iterator();
-      while (iter.hasNext())
-      {
-         ReferenceInfo info = (ReferenceInfo)iter.next();
-         
-         addFromRefInfo(info, refMap);
-      }
-   }
-        
-   // Private --------------------------------------------------------------------------------------
-   
-   protected 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);
-      
-      ref.setScheduledDeliveryTime(info.getScheduledDelivery());
-      
-      //Schedule the delivery if necessary, or just add to the in memory queue
-      if (!checkAndSchedule(ref))
-      {
-         messageRefs.addLast(ref, ref.getMessage().getPriority());
-      }
-      
-      return ref;
-   }
-   
-
-   protected 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;
-   }  
-  
-}

Deleted: trunk/src/main/org/jboss/messaging/core/Queue.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/Queue.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/Queue.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,40 +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;
-
-/**
- * A Queue
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public interface Queue extends Channel
-{
-   String getName();
-   
-   Filter getFilter();
-   
-   boolean isClustered();
-}

Deleted: trunk/src/main/org/jboss/messaging/core/Receiver.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/Receiver.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/Receiver.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,52 +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.message.MessageReference;
-import org.jboss.messaging.core.tx.Transaction;
-
-/**
- * A component that handles routable instances. Handling means consumption or
- * synchronous/asynchronous forwarding to another receiver(s).
- *
- * @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 Receiver
-{
-
-   /**
-    * A receiver can return an active, "done" or null delivery. The method returns null in case
-    * the receiver doesn't accept the message. The return value is <i>unspecified</i> when the
-    * message is submitted in the context of a transaction (tx not null).
-    *
-    * @param observer - the component the delivery should be acknowledged to.
-    * 
-    * @see org.jboss.messaging.core.Delivery
-    * @see org.jboss.messaging.core.DeliveryObserver
-    */
-   Delivery handle(DeliveryObserver observer, MessageReference reference, Transaction tx);
-     
-}

Deleted: trunk/src/main/org/jboss/messaging/core/Router.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/Router.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/Router.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,37 +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;
-
-
-/**
- * 
- * 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>
- * 
- * $Id$
- */
-public interface Router extends Distributor, Receiver
-{
-}

Deleted: trunk/src/main/org/jboss/messaging/core/SimpleDelivery.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/SimpleDelivery.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/SimpleDelivery.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,153 +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 org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.tx.Transaction;
-
-/**
- * A simple Delivery implementation.
- *
- * @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 SimpleDelivery implements Delivery
-{
-   // Constants ------------------------------------------------------------------------------------
-
-   // Static ---------------------------------------------------------------------------------------
-   
-   private static final Logger log = Logger.getLogger(SimpleDelivery.class);
-   
-   // Attributes -----------------------------------------------------------------------------------
-
-   protected volatile boolean done;
-   protected boolean selectorAccepted;
-   protected DeliveryObserver observer;
-   protected MessageReference reference;
-
-   private boolean trace = log.isTraceEnabled();
-
-   // Constructors ---------------------------------------------------------------------------------
-
-   public SimpleDelivery()
-   {
-      this(null, null, false);
-   }
-
-   public SimpleDelivery(boolean d)
-   {
-      this(null, null, d);
-   }
-
-   public SimpleDelivery(DeliveryObserver observer, MessageReference reference)
-   {
-      this(observer, reference, false);
-   }
-
-   public SimpleDelivery(MessageReference reference, boolean done)
-   {
-      this(null, reference, done);
-   }
-
-   public SimpleDelivery(DeliveryObserver observer, MessageReference reference, boolean done)
-   {
-      this.done = done;
-      this.reference = reference;
-      this.observer = observer;
-      this.selectorAccepted = true;
-   }
-
-   public SimpleDelivery(DeliveryObserver observer, MessageReference reference, boolean done,
-                         boolean selectorAccepted)
-   {
-      this.done = done;
-      this.reference = reference;
-      this.observer = observer;
-      this.selectorAccepted = selectorAccepted;
-   }
-
-   // Delivery implementation ----------------------------------------------------------------------
-
-   public MessageReference getReference()
-   {
-      return reference;
-   }
-
-   public boolean isDone()
-   {
-      return done;
-   }
-   
-   public boolean isSelectorAccepted()
-   {
-      return selectorAccepted;
-   }
-
-   public void setObserver(DeliveryObserver observer)
-   {
-      this.observer = observer;
-   }
-
-   public DeliveryObserver getObserver()
-   {
-      return observer;
-   }
-
-   public void acknowledge(Transaction tx) throws Throwable
-   {        
-      if (trace) { log.trace(this + " acknowledging delivery " + ( tx == null ? "non-transactionally" : "in " + tx)); }
-      
-      observer.acknowledge(this, tx);
-
-      done = true;      
-   }
-
-   public void cancel() throws Throwable
-   {
-      if (trace) { log.trace(this + " cancelling delivery"); }
-         
-      observer.cancel(this);
-      
-      done = true;
-   }
-   
-   // Public ---------------------------------------------------------------------------------------
-
-   public String toString()
-   {
-      return "Delivery" + (reference == null ? "" : "[" + reference + "]") +
-         "(" + ( done ? "done" : "active") + ")";
-   }
-
-   // Package protected ----------------------------------------------------------------------------
-   
-   // Protected ------------------------------------------------------------------------------------
-   
-   // Private --------------------------------------------------------------------------------------
-   
-   // Inner classes --------------------------------------------------------------------------------
-}

Added: trunk/src/main/org/jboss/messaging/core/contract/Binding.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/Binding.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/Binding.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,45 @@
+/*
+ * 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.contract;
+
+/**
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: $</tt>21 Jun 2007
+ *
+ * $Id: $
+ *
+ */
+public class Binding
+{
+	public Binding(Condition condition, Queue queue)
+	{
+		this.condition = condition;
+		
+		this.queue = queue;
+	}
+	
+	public Condition condition;
+	
+	public Queue queue;
+}
\ No newline at end of file

Copied: trunk/src/main/org/jboss/messaging/core/contract/Channel.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/Channel.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/Channel.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/Channel.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,141 @@
+/*
+  * 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.contract;
+
+import java.util.List;
+
+/**
+ * A Channel is a transactional, reliable message delivery mechanism that forwards a message from a
+ * sender to one or more 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>
+ *
+ * $Id$
+ */
+public interface Channel extends DeliveryObserver, Receiver
+{
+   /**    
+    * @return the unique ID of the channel
+    */
+   long getChannelID();
+
+   /**
+    * @return true if the channel can guarantee recoverability for <i>reliable</i> messages.
+    *         Recoverability is not guaranteed for non-reliable messages even if the channel is recoverable.
+    */
+   boolean isRecoverable();
+
+   /**
+    * @param filter - may be null, in which case no filter is applied.
+    *
+    * @return a List containing message references of messages whose state is maintained by this
+    *         State instance. 
+    */
+   List browse(Filter filter);
+
+   /**
+    * Delivers as many references as possible to its router until receivers will accept no more
+    */
+   void deliver();
+
+   /**
+    * Close the channel
+    */
+   void close();
+
+   /**
+    * @return Total message count = undelivered + delivering + scheduled
+    */
+   int getMessageCount();
+   
+   /**
+    * @return Count being delivered
+    */
+   int getDeliveringCount();
+   
+   /**
+    * Count scheduled for delivery
+    */
+   int getScheduledCount();
+   
+   /**
+    * Remove all the references in the channel
+    * @throws Throwable
+    */
+   void removeAllReferences() throws Throwable;
+   
+   /**
+    * Load any references for this channel from storage
+    * @throws Exception
+    */
+   void load() throws Exception;
+   
+   /**
+    * Unload any references for this channel
+    * @throws Exception
+    */
+   void unload() throws Exception;
+   
+   /**
+    * Activate the channel.
+    */
+   void activate();
+   
+   /**
+    * Deactivate the channel
+    */
+   void deactivate();
+   
+   /**
+    * @return true if the channel is active
+    */
+   boolean isActive();
+   
+   /**
+    * Given a List of message ids, create a list of deliveries for them
+    * @param messageIds
+    * @return
+    */
+   List recoverDeliveries(List messageIds);
+  
+   /**
+    * 
+    * @return The maxiumum number of references this channel can store
+    */
+   int getMaxSize();
+   
+   /**
+    * Set the maximum number of references this channel can store
+    * @param newSize
+    */
+   void setMaxSize(int newSize);
+   
+   /**
+    * Get the total number of messages added since this channel was started
+    * @return
+    */
+   int getMessagesAdded();
+}
+
+

Added: trunk/src/main/org/jboss/messaging/core/contract/ClusterNotification.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/ClusterNotification.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/ClusterNotification.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,70 @@
+/*
+  * 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.contract;
+
+/**
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: $</tt>21 Jun 2007
+ *
+ * $Id: $
+ *
+ */
+public class ClusterNotification
+{
+	public static final int TYPE_BIND = 0;
+	
+	public static final int TYPE_UNBIND = 1;
+	
+	public static final int TYPE_FAILOVER_START = 2;
+	
+	public static final int TYPE_FAILOVER_END = 3;
+	
+	public static final int TYPE_NODE_JOIN = 4;
+	
+	public static final int TYPE_NODE_LEAVE = 5;
+	
+	public static final int TYPE_REPLICATOR_PUT = 6;
+	
+	public static final int TYPE_REPLICATOR_REMOVE = 7;
+		
+	public int type;
+	
+	public int nodeID;
+	
+	public Object data;
+	
+	public ClusterNotification(int type, int nodeID, Object data)
+	{
+		this.type = type;
+		
+		this.nodeID = nodeID;
+		
+		this.data = data;
+	}
+	
+	public String toString()
+	{
+		return "ClusterNotification:" + System.identityHashCode(this) + " type: " + type + " nodeID: " + nodeID + " data: " + data;
+	}
+}

Added: trunk/src/main/org/jboss/messaging/core/contract/ClusterNotificationListener.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/ClusterNotificationListener.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/ClusterNotificationListener.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.contract;
+
+/**
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: $</tt>21 Jun 2007
+ *
+ * $Id: $
+ *
+ */
+public interface ClusterNotificationListener
+{
+	void notify(ClusterNotification notification);
+}

Added: trunk/src/main/org/jboss/messaging/core/contract/ClusterNotifier.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/ClusterNotifier.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/ClusterNotifier.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,41 @@
+/*
+  * 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.contract;
+
+
+/**
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: $</tt>21 Jun 2007
+ *
+ * $Id: $
+ *
+ */
+public interface ClusterNotifier
+{
+	void registerListener(ClusterNotificationListener listener);
+	
+	void unregisterListener(ClusterNotificationListener listener);
+	
+	void sendNotification(ClusterNotification notification);
+}

Copied: trunk/src/main/org/jboss/messaging/core/contract/Condition.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/plugin/contract/Condition.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/Condition.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/Condition.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.messaging.core.contract;
+
+
+/**
+ * A Condition
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ *
+ */
+public interface Condition
+{
+   String toText();
+}

Copied: trunk/src/main/org/jboss/messaging/core/contract/ConditionFactory.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/plugin/contract/ConditionFactory.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/ConditionFactory.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/ConditionFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.messaging.core.contract;
+
+
+/**
+ * A ConditionFactory
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ *
+ */
+public interface ConditionFactory
+{
+   Condition createCondition(String text) throws Exception;
+}

Copied: trunk/src/main/org/jboss/messaging/core/contract/Delivery.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/Delivery.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/Delivery.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/Delivery.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,49 @@
+/*
+  * 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.contract;
+
+import org.jboss.messaging.core.impl.tx.Transaction;
+
+/**
+ * A message delivery. It can be "done" or active.
+ * 
+ * @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 Delivery
+{
+   MessageReference getReference();
+
+   DeliveryObserver getObserver();
+
+   // TODO this doesn't actually belong in the delivery, the selector should be moved "inside"
+   //      the channel. See http://jira.jboss.org/jira/browse/JBMESSAGING-275
+
+   boolean isSelectorAccepted();
+   
+   void acknowledge(Transaction tx) throws Throwable;
+
+   void cancel() throws Throwable;   
+}

Copied: trunk/src/main/org/jboss/messaging/core/contract/DeliveryObserver.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/DeliveryObserver.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/DeliveryObserver.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/DeliveryObserver.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.messaging.core.contract;
+
+import org.jboss.messaging.core.impl.tx.Transaction;
+
+/**
+ * @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 DeliveryObserver
+{
+   void acknowledge(Delivery d, Transaction tx) throws Throwable;
+
+   void cancel(Delivery d) throws Throwable;
+}

Copied: trunk/src/main/org/jboss/messaging/core/contract/Distributor.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/Distributor.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/Distributor.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/Distributor.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,74 @@
+/*
+  * 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.contract;
+
+import java.util.Iterator;
+
+
+/**
+ * A Distributor takes a message and distributes it to one or more Receivers
+ * 
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * 
+ * $Id$
+ */
+public interface Distributor extends Receiver
+{
+	/**
+	 * Does the distributor already contain the specified Receiver?
+	 * @param receiver
+	 * @return
+	 */
+   boolean contains(Receiver receiver);
+
+   /**
+    * @return an iterator of receivers
+    */
+   Iterator iterator();
+
+   /**
+    * Add a local receiver to this distributor.
+    *
+    * @return true if the distributor did not already contain the specified receiver and the
+    *         receiver was added to the distributor, false otherwise.
+    */
+   boolean add(Receiver receiver);
+
+   /**
+    * Remove a local receiver from this distributor.
+    *
+    * @return true if this distributor contained the specified receiver.
+    */
+   boolean remove(Receiver receiver);
+
+   /**
+    * Remove all receivers.
+    */
+   void clear();
+   
+   /**
+    * 
+    * @return The number of receivers in the distributor
+    */
+   int getNumberOfReceivers();
+}

Added: trunk/src/main/org/jboss/messaging/core/contract/FailoverMapper.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/FailoverMapper.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/FailoverMapper.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,44 @@
+/*
+ * 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.contract;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A FailoverMapper
+ * 
+ * Determines the mapping between a set of nodes and their failover nodes
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1917 $</tt>
+ *
+ * $Id: FailoverMapper.java 1917 2007-01-08 20:26:12Z clebert.suconic at jboss.com $
+ *
+ */
+public interface FailoverMapper
+{
+   /**
+    * @param nodes Set<Integer>.
+    */
+   Map generateMapping(Set nodes);
+}

Copied: trunk/src/main/org/jboss/messaging/core/contract/Filter.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/Filter.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/Filter.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/Filter.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,45 @@
+/*
+  * 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.contract;
+
+
+/**
+ * A filter encapsulates the logic of whether to accept a message or not. Filters are used when
+ * browsing to restrict the messages browsed, or when routing messages.
+ *
+ * @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$</tt>
+ *
+ * $Id$
+ */
+public interface Filter
+{
+	/**
+	 * Tests whether the message should be accepted.
+    *
+	 * @return true if the Filter accepts the message - i.e. let's it pass.
+	 */
+	boolean accept(Message message);
+   
+   String getFilterString();
+}

Copied: trunk/src/main/org/jboss/messaging/core/contract/FilterFactory.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/FilterFactory.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/FilterFactory.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/FilterFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,41 @@
+/*
+ * 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.contract;
+
+
+
+/**
+ * A FilterFactory
+ * 
+ * This exists so we can abstract out the creation of filters inside core code so
+ * we don't have dependencies on jms selectors
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ *
+ */
+public interface FilterFactory
+{
+   Filter createFilter(String filterString) throws Exception;
+}

Copied: trunk/src/main/org/jboss/messaging/core/contract/JChannelFactory.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/jchannelfactory/JChannelFactory.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/JChannelFactory.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/JChannelFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,16 @@
+package org.jboss.messaging.core.contract;
+
+import org.jgroups.JChannel;
+
+/**
+ * @author <a href="mailto:clebert.suconic at jboss.org">Clebert Suconic</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ */
+public interface JChannelFactory
+{
+   JChannel createSyncChannel() throws Exception;
+   
+   JChannel createASyncChannel() throws Exception;
+}

Copied: trunk/src/main/org/jboss/messaging/core/contract/MemoryManager.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/memory/MemoryManager.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/MemoryManager.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/MemoryManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.messaging.core.contract;
+
+
+/**
+ * A MemoryManager
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ *
+ */
+public interface MemoryManager extends MessagingComponent
+{
+   boolean isMemoryLow();    
+}

Copied: trunk/src/main/org/jboss/messaging/core/contract/Message.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/message/Message.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/Message.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/Message.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,159 @@
+/*
+  * 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.contract;
+
+import java.util.Map;
+
+import org.jboss.messaging.util.Streamable;
+
+/**
+ * A message is a routable instance that has a payload.
+ * The payload is opaque to the messaging system.
+ *
+ * @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 interface Message extends Streamable
+{
+	/**
+	 * This header is set on a message when a message is sucked from one node of the cluster to another
+	 * and order preservation is true.
+	 * The header is checked when sucking messages and if order preservation is true then the message is not accepted.
+	 * This is a basic way of ensuring message order is preserved.
+	 */
+	public static final String CLUSTER_SUCKED = "CLUSTER_SUCKED";
+	
+   /**    
+    * @return The unique id of the message
+    */
+   long getMessageID();
+
+   /**
+    * @return true if the delivery must be guaranteed for this routable, false otherwise.
+    */
+   boolean isReliable();
+   
+   /**
+    * @return the time when this routable expires and must be removed
+    *         from the system. A zero value means this routable never expires.
+    */
+   long getExpiration();
+
+   /**
+    * 
+    * @return true if the message has expired
+    */
+   boolean isExpired();
+   
+   /**
+    * Set the expiration for this message
+    * 
+    * @param expiration
+    */
+   void setExpiration(long expiration);
+   
+   /**
+    * @return the time (in GMT milliseconds) when this routable was delivered to the provider.
+    */
+   long getTimestamp();
+   
+   byte getPriority();
+   
+   /**
+    * Get the priority of the message. Priorities range from 0 to 9.
+    * Where 0 is the lowest priority and 9 is the highest priority
+    * @param priority
+    */
+   void setPriority(byte priority);
+
+   /**
+    * Binds a header. If the header map previously contained a mapping for this name, the old value
+    * is replaced by the specified value.
+    *
+    * @return the value associated with the name or null if there is no mapping for the name. A null
+    *         can also indicate that the header map previously associated null with the specified
+    *         name.
+    */
+   Object putHeader(String name, Object value);
+
+   /**
+    * Returns the value corresponding to the header name. Returns null if the map contains no
+    * mapping for the name. A return value of null does not necessarily indicate that the map
+    * contains no mapping for the name; it's also possible that the map explicitly maps the name to
+    * null. The containsHeader() operation may be used to distinguish these two cases.
+    *
+    * @return the value associated with the header, or null if there is no mapping for the header.
+    */
+   Object getHeader(String name);
+
+   /**
+    * Removes the header.
+    *
+    * @return previous value associated with the header, or null if there was no mapping.
+    */
+   Object removeHeader(String name);
+
+   /**
+    * Returns true if the Routable contains the specified header.
+    */
+   boolean containsHeader(String name);
+      
+   /**
+    * 
+    * @return The message's headers
+    */
+   Map getHeaders();
+   
+   /**
+    * 
+    * @return The message's payload
+    */
+   Object getPayload();
+   
+   /**
+    * 
+    * @return The message's payload in byte[] form
+    */
+   byte[] getPayloadAsByteArray();
+    
+   /**
+    * 
+    * @return true if the message has already been persisted
+    */
+   boolean isPersisted();
+   
+   /**
+    * Set the message's persisted state to the specified value
+    * @param persisted
+    */
+   void setPersisted(boolean persisted);
+   
+   /**
+    * 
+    * @return the type of the message
+    */
+   byte getType();
+   
+}

Copied: trunk/src/main/org/jboss/messaging/core/contract/MessageReference.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/message/MessageReference.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/MessageReference.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/MessageReference.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,67 @@
+/*
+  * 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.contract;
+
+/**
+ * A reference to a message.
+ * 
+ * Channels store message references rather than the messages themselves.
+ * 
+ * If many channels have contain the same reference this makes a lot of sense
+ * 
+ * @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 MessageReference
+{      
+   long getPagingOrder();
+   
+   void setPagingOrder(long order);   
+   
+   void releaseMemoryReference();
+   
+   MessageReference copy();
+   
+   Message getMessage();
+   
+   /**
+    * 
+    * @return The time in the future that delivery will be delayed until, or zero if
+    * no scheduled delivery will occur
+    */
+   long getScheduledDeliveryTime();
+   
+   void setScheduledDeliveryTime(long scheduledDeliveryTime);
+   
+   /**
+    * @return the number of times delivery has been attempted for this routable
+    */
+   int getDeliveryCount();
+   
+   void setDeliveryCount(int deliveryCount);
+   
+   
+
+}

Copied: trunk/src/main/org/jboss/messaging/core/contract/MessageStore.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/plugin/contract/MessageStore.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/MessageStore.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/MessageStore.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,44 @@
+/**
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.messaging.core.contract;
+
+
+/**
+ * An interface to a referencing/dereferencing message store.
+ *
+ * @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$</ttH>
+ *
+ * $Id$
+ */
+public interface MessageStore extends MessagingComponent
+{
+   /**
+    * 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
+    *
+    * @param m The Message for which to create the MessageReference
+    * @return The new MessageReference
+    */
+   MessageReference reference(Message m);
+   
+   /**
+    * Return a new reference for a message already stored in the store and identified by <messageID>
+    * @param messageID
+    * @return The reference or null if the message is not already stored in the store
+    */
+   MessageReference reference(long messageID);
+
+   /**
+    * Remove a message from the store
+    * 
+    * @param messageID
+    * @return
+    */
+   public boolean forgetMessage(long messageID);   
+}

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

Copied: trunk/src/main/org/jboss/messaging/core/contract/PersistenceManager.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/PersistenceManager.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/PersistenceManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,174 @@
+/*
+  * 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.contract;
+
+import java.util.List;
+
+import org.jboss.messaging.core.impl.tx.Transaction;
+
+/**
+ * The interface to the persistence manager.
+ *
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:Konda.Madhu at uk.mizuho-sc.com">Madhu Konda</a>
+ * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
+ *
+ * @version <tt>1.1</tt>
+ *
+ * PersistenceManager.java,v 1.1 2006/02/22 17:33:42 timfox Exp
+ */
+public interface PersistenceManager extends MessagingComponent
+{
+   void addReference(long channelID, MessageReference ref, Transaction tx) throws Exception;
+
+   void removeReference(long channelID, MessageReference ref, Transaction tx) throws Exception;
+   
+   void updateDeliveryCount(long channelID, MessageReference ref) throws Exception;
+   
+   // XA Recovery functionality
+   
+   List retrievePreparedTransactions() throws Exception;
+   
+   List getMessageChannelPairRefsForTx(long transactionId) throws Exception;
+
+   List getMessageChannelPairAcksForTx(long transactionId) throws Exception;
+
+      
+   // Paging functionality - TODO we should split this out into its own interface
+
+   void pageReferences(long channelID, List references, boolean paged) throws Exception;
+   
+   void removeDepagedReferences(long channelID, List refs) throws Exception;
+    
+   void updatePageOrder(long channelID, List references) throws Exception;
+   
+   void updateReferencesNotPagedInRange(long channelID, long orderStart, long orderEnd, long num) throws Exception;
+   
+   List getPagedReferenceInfos(long channelID, long orderStart, int number) throws Exception;
+   
+   InitialLoadInfo loadFromStart(long channelID, int fullSize) throws Exception;
+   
+   InitialLoadInfo mergeAndLoad(long fromChannelID, long toChannelID, int numberToLoad,
+                                long firstPagingOrder, long nextPagingOrder) 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;
+   
+   // Failover elated functionality (checkDuplicates on send)
+
+   boolean referenceExists(long messageID) throws Exception;
+
+   // Interface value classes ----------------------------------------------------------------------
+
+   class MessageChannelPair
+   {
+      private Message message;
+      
+      private long channelId;
+      
+      public MessageChannelPair(Message message, long channelId)
+      {
+         this.message = message;
+         
+         this.channelId = channelId;
+      }
+      
+      public Message getMessage()
+      {
+         return message;
+      }
+      
+      public long getChannelId()
+      {
+         return channelId;
+      }
+   }
+   
+   class ReferenceInfo
+   {
+      private long messageId;
+      
+      private int deliveryCount;
+      
+      private long scheduledDelivery;
+      
+      public ReferenceInfo(long msgId, int deliveryCount, long scheduledDelivery)
+      {
+         this.messageId = msgId;
+         
+         this.deliveryCount = deliveryCount;
+         
+         this.scheduledDelivery = scheduledDelivery;
+      }    
+      
+      public long getMessageId()
+      {
+         return messageId;
+      }
+ 
+      public int getDeliveryCount()
+      {
+         return deliveryCount;
+      }      
+      
+      public long getScheduledDelivery()
+      {
+         return scheduledDelivery;
+      }
+   }
+   
+   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;
+      }
+   }
+   
+}

Copied: trunk/src/main/org/jboss/messaging/core/contract/PostOffice.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/plugin/contract/PostOffice.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/PostOffice.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/PostOffice.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,143 @@
+/*
+ * 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.contract;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.messaging.core.impl.tx.Transaction;
+
+/**
+ * 
+ * A post office holds bindings of queues to conditions.
+ * 
+ * When routing a reference, the post office routes the reference to any binding whose condition matches
+ * the condition specified in the call to route(...)
+ * 
+ * A queue can only be bound with one condition in the post office
+ * 
+ * Each queue must have a unique name and channel ID
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ *
+ */
+public interface PostOffice extends MessagingComponent
+{
+	/**
+	 * Get the name of the post office
+	 * 
+	 * @return The name of this post office
+	 */
+   String getOfficeName();
+   
+   /**
+    * Add a binding to the post office
+    * @param binding The binding to add
+    * @param allNodes Add this binding on ALL nodes?
+    * @throws Exception
+    */
+   void addBinding(Binding binding, boolean allNodes) throws Exception;
+
+   /**
+    * Remove a binding from the post office
+    * @param queueName The queue name that identifies the binding
+    * @param allNodes Remove this binding from ALL node?
+    * @throws Throwable
+    */
+   void removeBinding(String queueName, boolean allNodes) throws Throwable;
+   
+   /**
+    * Route a reference.
+    *
+    * @param condition - the message will be routed to queue(s) if the specified condition matches the
+    *        condition of the bindings.
+    * @param tx - the transaction or null if not in the context of a transaction.
+    *
+    * @return true if reference was accepted by at least one queue.
+    */
+   boolean route(MessageReference ref, Condition condition, Transaction tx) throws Exception; 
+   
+   /**
+    * Get all queues that match the condition
+    * @param condition The condition
+    * @param localOnly Only retrieve local queues ?
+    * @return
+    * @throws Exception
+    */
+   Collection getQueuesForCondition(Condition condition, boolean localOnly) throws Exception;
+   
+   /**
+    * Get the binding with the specified queue name
+    * @param queueName
+    * @return
+    * @throws Exception
+    */
+   Binding getBindingForQueueName(String queueName) throws Exception;
+   
+   /**
+    * Get the binding with the specified channel ID
+    * @param channelID
+    * @return
+    * @throws Exception
+    */
+   Binding getBindingForChannelID(long channelID) throws Exception;
+   
+   /**
+    * Get all bindings with the specified queue name (They will be on different nodes)
+    * @param queueName
+    * @return
+    * @throws Exception
+    */
+   Collection getAllBindingsForQueueName(String queueName) throws Exception;
+   
+   /**
+    * Get all the bindings
+    * @return
+    * @throws Exception
+    */
+   Collection getAllBindings() throws Exception;
+   
+   /**
+    * Is this post office clustered?
+    * 
+    * @return true If the post office is clustered
+    */
+   boolean isClustered();   
+
+   /**
+    * Get the failover map
+    * @return
+    */
+   Map getFailoverMap();
+   
+   /**
+    * Get a set of nodes in the cluster
+    * @return
+    */
+   Set nodeIDView();
+}

Copied: trunk/src/main/org/jboss/messaging/core/contract/Queue.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/Queue.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/Queue.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/Queue.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,76 @@
+/*
+ * 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.contract;
+
+import org.jboss.messaging.core.impl.clusterconnection.MessageSucker;
+
+
+/**
+ * A Queue
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ *
+ */
+public interface Queue extends Channel
+{
+   Filter getFilter();
+   
+   /**
+    * Merge the contents of one queue with another - this happens at failover when a queue is failed
+    * over to another node, but a queue with the same name already exists. In this case we merge the
+    * two queues.
+    */
+   void mergeIn(long channelID) throws Exception;
+   
+   /* 
+    * TODO - this method does not really belong here - the only reason it is, is because we create the 
+    * queues in the post office on startup but paging info is only known at deploy time
+    */
+   void setPagingParams(int fullSize, int pageSize, int downCacheSize);
+   
+   int getFullSize();
+   
+   int getPageSize();
+   
+   int getDownCacheSize();
+   
+   boolean isPreserveOrdering();
+   
+   void setPreserveOrdering(boolean preserveOrdering);
+   
+   boolean isClustered();
+   
+   String getName();
+   
+   int getNodeID();
+   
+   Distributor getLocalDistributor();
+   
+   Distributor getRemoteDistributor();   
+   
+   void registerSucker(MessageSucker sucker);
+   
+   boolean unregisterSucker(MessageSucker sucker);
+}

Copied: trunk/src/main/org/jboss/messaging/core/contract/Receiver.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/Receiver.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/Receiver.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/Receiver.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,54 @@
+/*
+  * 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.contract;
+
+import org.jboss.messaging.core.impl.tx.Transaction;
+
+/**
+ * A component that handles MessageReferences.
+ * 
+ * Handling means consumption or forwarding to another receiver(s).
+ * 
+ * Handling can be done transactionally or non transactionally
+ *
+ * @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 Receiver
+{
+
+   /**
+    * A receiver can return an active, "done" or null delivery. The method returns null in case
+    * the receiver doesn't accept the message. The return value is <i>unspecified</i> when the
+    * message is submitted in the context of a transaction (tx not null).
+    *
+    * @param observer - the component the delivery should be acknowledged to.
+    * 
+    * @see org.jboss.messaging.core.contract.Delivery
+    * @see org.jboss.messaging.core.contract.DeliveryObserver
+    */
+   Delivery handle(DeliveryObserver observer, MessageReference reference, Transaction tx);
+     
+}

Copied: trunk/src/main/org/jboss/messaging/core/contract/Replicator.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/plugin/contract/Replicator.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/Replicator.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/contract/Replicator.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,68 @@
+/*
+ * 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.contract;
+
+import java.io.Serializable;
+import java.util.Map;
+
+
+/**
+ * A Replicator
+ * 
+ * This is used for replicating arbitrary data across a cluster.
+ * 
+ * Data is structured as follows:
+ * 
+ * There is an arbitrary key to identify the data, e.g. the connection factory name
+ * Then, for that key, there is an entry for each node id.
+ *
+ * @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$</tt>
+ *
+ * $Id$
+ *
+ */
+public interface Replicator
+{
+   public static final String CF_PREFIX = "CF_";
+ 
+   /**
+    * Broadcast data across the cluster, updating replication maps on all nodes, including the local
+    * node.
+    */
+   void put(Serializable key, Serializable data) throws Exception;
+
+   /**
+    * Return a node-mapped replicated data.
+    *
+    * @return a Map<Integer(nodeID)-data>. Returns an empty map if no replicants are found for
+    *         'key', but never null.
+    */
+   Map get(Serializable key) throws Exception;
+
+   /**
+    * Updates the replication maps across the cluster by removing the data corresponding to the give
+    * key. Only the data corresponding to the current node is removed.
+    */
+   boolean remove(Serializable key) throws Exception;   
+}

Copied: trunk/src/main/org/jboss/messaging/core/impl/ChannelSupport.java (from rev 2784, trunk/src/main/org/jboss/messaging/core/ChannelSupport.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/ChannelSupport.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/ChannelSupport.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,1038 @@
+/*
+ * 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.impl;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+
+import org.jboss.jms.server.MessagingTimeoutFactory;
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.contract.Channel;
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.DeliveryObserver;
+import org.jboss.messaging.core.contract.Distributor;
+import org.jboss.messaging.core.contract.Filter;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.PersistenceManager;
+import org.jboss.messaging.core.contract.Receiver;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.core.impl.tx.TransactionException;
+import org.jboss.messaging.core.impl.tx.TxCallback;
+import org.jboss.messaging.util.prioritylinkedlist.BasicPriorityLinkedList;
+import org.jboss.messaging.util.prioritylinkedlist.PriorityLinkedList;
+import org.jboss.util.timeout.Timeout;
+import org.jboss.util.timeout.TimeoutTarget;
+
+import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt;
+
+/**
+ * 
+ * This class provides much of the functionality needed to implement a channel.
+ * 
+ * This partial implementation supports atomicity, isolation and recoverability for 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: ChannelSupport.java,v 1.65
+ *          2006/06/27 19:44:39 timfox Exp $
+ */
+public abstract class ChannelSupport implements Channel
+{
+   // Constants ------------------------------------------------------------------------------------
+
+   private static final Logger log = Logger.getLogger(ChannelSupport.class);
+
+   // Static ---------------------------------------------------------------------------------------
+
+   // Attributes -----------------------------------------------------------------------------------
+
+   private boolean trace = log.isTraceEnabled();
+
+   protected long channelID;
+
+   protected Distributor distributor;
+
+   protected MessageStore ms;
+
+   protected boolean receiversReady;
+
+   protected PriorityLinkedList messageRefs;
+
+   protected boolean recoverable;
+
+   protected PersistenceManager pm;
+
+   protected Object lock;
+
+   protected boolean active;
+   
+   //TODO - I would like to get rid of this - the only reason we still keep a count of
+   //refs being delivered is because many tests require this
+   //Having to keep this count requires synchronization between delivery thread and acknowledgement
+   //thread which will hamper concurrency
+   //Suggest that we have a flag that disables this for production systems
+   protected SynchronizedInt deliveringCount;
+    
+   protected Set scheduledDeliveries;
+   
+   //The maximum number of refs this queue can hold, or -1 if no limit
+   //If any more refs are added after this point they are dropped
+   protected int maxSize;
+  
+   protected SynchronizedInt messagesAdded;
+    
+   // Constructors ---------------------------------------------------------------------------------
+
+   protected ChannelSupport(long channelID, MessageStore ms, PersistenceManager pm,
+                            boolean recoverable, int maxSize)
+   {
+      if (trace) { log.trace("creating " + (pm != null ? "recoverable " : "non-recoverable ") + "channel[" + channelID + "]"); }
+
+      this.ms = ms;
+
+      this.pm = pm;
+
+      this.channelID = channelID;
+
+      this.recoverable = recoverable;
+
+      messageRefs = new BasicPriorityLinkedList(10);
+
+      lock = new Object();
+      
+      deliveringCount = new SynchronizedInt(0);
+      
+      scheduledDeliveries = new HashSet();
+      
+      this.maxSize = maxSize;
+      
+      messagesAdded = new SynchronizedInt(0);
+   }
+   
+   // Receiver implementation ----------------------------------------------------------------------
+
+   public Delivery handle(DeliveryObserver sender, MessageReference ref, Transaction tx)
+   {
+      if (!isActive())
+      {	
+      	if (trace) { log.trace(this + " is not active, returning null delivery for " + ref); }
+      	
+         return null;
+      }
+
+      checkClosed();
+      
+      return handleInternal(sender, ref, tx, true);      
+   }
+
+   // DeliveryObserver implementation --------------------------------------------------------------
+
+   public void acknowledge(Delivery d, Transaction tx) throws Throwable
+   {
+      if (trace) { log.trace("acknowledging " + d + (tx == null ? " non-transactionally" : " transactionally in " + tx)); }
+
+      acknowledgeInternal(d, tx, true);
+   }
+
+   public void cancel(Delivery del) throws Throwable
+   {
+      //We may need to update the delivery count in the database
+      
+      MessageReference ref = del.getReference();
+      
+      if (ref.getMessage().isReliable())
+      {
+         pm.updateDeliveryCount(this.channelID, ref);
+      }
+            
+      deliveringCount.decrement();
+
+      if (!checkAndSchedule(ref))
+      {
+         cancelInternal(ref);
+      }
+   }      
+        
+   // Channel implementation -----------------------------------------------------------------------
+
+   public long getChannelID()
+   {
+      return channelID;
+   }
+
+   public boolean isRecoverable()
+   {
+      return recoverable;
+   }
+
+   public List browse(Filter filter)
+   {
+      if (trace) { log.trace(this + " browse" + (filter == null ? "" : ", filter = " + filter)); }
+
+      synchronized (lock)
+      {
+         //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 = undelivered(filter);
+
+         // dereference pass
+         ArrayList messages = new ArrayList(references.size());
+         for (Iterator i = references.iterator(); i.hasNext();)
+         {
+            MessageReference ref = (MessageReference) i.next();
+            messages.add(ref.getMessage());
+         }
+         return messages;
+      }      
+   }
+ 
+   public void deliver()
+   {
+      checkClosed();
+      
+      synchronized (lock)
+      {      
+	      if (distributor != null && distributor.getNumberOfReceivers() > 0)
+	      {                
+	         setReceiversReady(true);
+	            
+	         deliverInternal();                  
+	      }
+      }     
+   }      
+
+   public void close()
+   {
+   	synchronized (lock)
+   	{
+	      if (distributor != null)
+	      {
+	         distributor.clear();
+	         
+	         distributor = null;
+	      }
+	      
+	      clearAllScheduledDeliveries();
+   	}
+   }
+
+   /*
+    * This method clears the channel.
+    * Basically it consumes the rest of the messages in the channel.
+    * We can't just delete the corresponding references directly from the database since
+    * a) We might be paging
+    * b) The message might remain in the message store causing a leak
+    *
+    */
+   public void removeAllReferences() throws Throwable
+   {
+      log.debug(this + " removing all references");
+      
+      synchronized (lock)
+      {
+         if (deliveringCount.get() > 0)
+         {
+            throw new IllegalStateException("Cannot remove references while deliveries are in progress, there are " +
+            		                           deliveringCount.get());
+         }
+         
+         //Now we consume the rest of the messages
+         //This may take a while if we have a lot of messages including perhaps millions
+         //paged in the database - but there's no obvious other way to do it.
+         //We cannot just delete them directly from the database - because we may end up with messages leaking
+         //in the message store,
+         //also we might get race conditions when other channels are updating the same message in the db
+
+         //Note - we don't do this in a tx - because the tx could be too big if we have millions of refs
+         //paged in storage
+
+         MessageReference ref;
+         while ((ref = removeFirstInMemory()) != null)
+         {
+            SimpleDelivery del = new SimpleDelivery(this, ref);
+
+            del.acknowledge(null);
+
+            // Delivery#acknowledge decrements the deliveringCount without incrementing it first (because
+            // deliver has actually never been called), so increment it here to be accurate.  
+            deliveringCount.increment();
+         }
+      }
+      
+      clearAllScheduledDeliveries();
+   }
+
+   public List undelivered(Filter filter)
+   {
+      List undelivered = new ArrayList();
+
+      synchronized (lock)
+      {
+         Iterator iter = messageRefs.getAll().iterator();
+
+         while (iter.hasNext())
+         {
+            MessageReference r = (MessageReference) iter.next();
+
+            // TODO: I need to dereference the message each time I apply the
+            // filter. Refactor so the message reference will also contain JMS
+            // properties
+            if (filter == null || filter.accept(r.getMessage()))
+            {
+               undelivered.add(r);
+            }
+            else
+            {
+               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"); }
+
+      return undelivered;
+   }
+
+   /**
+    * Returns the count of messages stored AND being delivered AND scheduled
+    */
+   public int getMessageCount()
+   {
+      synchronized (lock)
+      {
+         return messageRefs.size() + getDeliveringCount() + getScheduledCount();
+      }
+   }
+   
+   public int getDeliveringCount()
+   {
+      return deliveringCount.get();
+   }
+   
+   public int getScheduledCount()
+   {
+      synchronized (scheduledDeliveries)
+      {
+         return scheduledDeliveries.size();
+      }
+   }
+
+   public void activate()
+   {
+      synchronized (lock)
+      {
+         active = true;         
+      }
+   }
+
+   public void deactivate()
+   {
+      synchronized (lock)
+      {
+         active = false;         
+      }
+   }
+
+   public boolean isActive()
+   {
+      synchronized (lock)
+      {
+         return active;         
+      }
+   }
+   
+   public List recoverDeliveries(List messageIds)
+   {
+      //debug
+      Iterator iter = messageIds.iterator();
+                  
+      List dels = new ArrayList();
+      
+      synchronized (lock)
+      {
+         ListIterator liter = messageRefs.iterator();
+                           
+         while (iter.hasNext())
+         {
+            Long id = (Long)iter.next();
+            
+            //Scan the queue
+            while (true)
+            {               
+               if (!liter.hasNext())
+               {
+                  // TODO we need to look in paging state too - currently not supported
+                  //http://jira.jboss.com/jira/browse/JBMESSAGING-839
+                  log.warn(this + " cannot find reference " + id + " (Might be paged!)");
+                  break;
+               }
+               
+               MessageReference ref = (MessageReference)liter.next();
+               
+               if (ref.getMessage().getMessageID() == id.longValue())
+               {
+                  liter.remove();
+                  
+                  Delivery del = new SimpleDelivery(this, ref);
+                  
+                  dels.add(del);
+                                 
+                  break;
+               }
+            }
+         }           
+      }
+            
+      return dels;
+   }
+   
+   public int getMaxSize()
+   {
+      synchronized (lock)
+      {
+         return maxSize;
+      }
+   }
+   
+   public void setMaxSize(int newSize)
+   {
+      synchronized (lock)
+      {
+         int count = getMessageCount();
+         
+         if (newSize != -1 && count > newSize)
+         {
+            log.warn("Cannot set maxSize to " + newSize + " since there are already " + count + " refs");
+         }
+         else
+         {
+            maxSize = newSize;
+         }
+      }
+   }
+   
+   public int getMessagesAdded()
+   {
+      return messagesAdded.get();
+   }
+
+   // Public ---------------------------------------------------------------------------------------
+
+   //Only used for testing
+   public int memoryRefCount()
+   {
+      synchronized (lock)
+      {
+         return messageRefs.size();
+      }
+   }
+
+   //Only used for testing
+
+   public String toString()
+   {
+      return "ChannelSupport[" + channelID + "]";
+   }
+
+   // Package protected ----------------------------------------------------------------------------
+   
+   // Protected ------------------------------------------------------------------------------------
+   
+   protected void clearAllScheduledDeliveries()
+   {
+      synchronized (scheduledDeliveries)
+      {
+         Set clone = new HashSet(scheduledDeliveries);
+         
+         Iterator iter = clone.iterator();
+         
+         while (iter.hasNext())
+         {
+            Timeout timeout = (Timeout)iter.next();
+            
+            timeout.cancel();
+         }
+         
+         scheduledDeliveries.clear();
+      }
+   }
+
+   protected void cancelInternal(MessageReference ref) throws Exception
+   {
+      if (trace) { log.trace(this + " cancelling " + ref + " in memory"); }
+
+      synchronized (lock)
+      {
+         messageRefs.addFirst(ref, ref.getMessage().getPriority());
+      }
+                  
+      if (trace) { log.trace(this + " added " + ref + " back into state"); }
+   }
+   
+   /**
+    * This methods delivers as many messages as possible to the distributor until no more deliveries are
+    * returned. This method should never be called at the same time as handle.
+    *
+    * @see org.jboss.messaging.core.contract.Channel#deliver()
+    */
+   protected void deliverInternal()
+   {
+      if (trace) { log.trace(this + " was prompted delivery"); }
+  
+      try
+      {
+         // The iterator is used to iterate through the refs in the channel in the case that they
+         // don't match the selectors of any receivers.
+         ListIterator iter = null;
+         
+         MessageReference ref = null;
+         
+         if (!getReceiversReady())
+         {
+         	if (trace) { log.trace(this + " receivers not ready so not delivering"); }
+         	
+         	log.info("There are " + this.distributor.getNumberOfReceivers() + " receivers");
+         	
+            return;
+         }
+         
+         while (true)
+         {           
+            ref = nextReference(iter);               
+                     
+            if (ref != null)
+            {
+               // Attempt to push the ref to a receiver
+               
+               if (trace) { log.trace(this + " pushing " + ref); }   
+               
+               Delivery del = distributor.handle(this, ref, null);
+               
+               setReceiversReady(del != null);
+               
+               if (del == null)
+               {
+                  // No receiver, broken receiver or full receiver so we stop delivering
+                  if (trace) { log.trace(this + " got no delivery for " + ref + " so no receiver got the message. Stopping delivery."); }
+                               
+                  break;
+               }
+               else if (!del.isSelectorAccepted())
+               {
+                  // No receiver accepted the message because no selectors matched, so we create
+                  // an iterator (if we haven't already created it) to iterate through the refs
+                  // in the channel. No delivery was really performed
+                  
+                  if (iter == null)
+                  {
+                     iter = messageRefs.iterator();
+                     
+                     //We just tried the first one, so we don't want to try it again
+                     iter.next();
+                  }                     
+               }
+               else
+               {
+                  if (trace) { log.trace(this + ": " + del + " returned for message " + ref); }
+                  
+                  // Receiver accepted the reference
+
+                  synchronized (lock)
+                  {
+                     if (iter == null)
+                     {
+                        if (trace) { log.trace(this + " removing first ref in memory"); } 
+                        
+                        removeFirstInMemory();
+                     }
+                     else
+                     {
+                        if (trace) { log.trace(this + " removed current message from iterator"); }                           
+                                    
+                        iter.remove();                                
+                     }
+                  }
+                                  
+                  deliveringCount.increment();                     
+               }               
+            }
+            else
+            {
+               // No more refs in channel or only ones that don't match any selectors
+               if (trace) { log.trace(this + " no more refs to deliver "); }
+               
+               break;
+            }            
+         }         
+      }
+      catch (Throwable t)
+      {
+         log.error(this + " Failed to deliver", t);
+      }
+   }
+   
+   protected boolean deliverScheduled(MessageReference ref)
+   {
+      try
+      {      
+         // We synchonize on the ref lock to prevent scheduled deivery kicking in before
+         // load has finished
+         synchronized (lock)
+         {
+            // Attempt to push the ref to a receiver
+            
+            if (trace) { log.trace(this + " pushing " + ref); }                                  
+   
+            Delivery del = distributor.handle(this, ref, null);
+   
+            setReceiversReady(del != null);
+            
+            if (del == null)
+            {
+               // No receiver, broken receiver or full receiver so we stop delivering
+               if (trace) { log.trace(this + ": no delivery returned for message" + ref + " so no receiver got the message. Delivery is now complete"); }
+   
+               return false;
+            }
+            else if (del.isSelectorAccepted())
+            {
+               if (trace) { log.trace(this + ": " + del + " returned for message:" + ref); }
+               
+               // Receiver accepted the reference
+               
+               deliveringCount.increment();                   
+               
+               return true;
+            }                
+         }
+      }
+      catch (Throwable t)
+      {
+         log.error(this + " Failed to deliver", t);
+      }
+      
+      return false;
+   }
+      
+   protected Delivery handleInternal(DeliveryObserver sender, MessageReference ref,
+                                     Transaction tx, boolean persist)
+   {
+      if (ref == null)
+      {
+         return null;
+      }
+
+      if (trace) { log.trace(this + " handles " + ref + (tx == null ? " non-transactionally" : " in transaction: " + tx)); }
+      
+      if (maxSize != -1 && getMessageCount() >= maxSize)
+      {
+         //Have reached maximum size - will drop message
+         
+         log.warn(this + " has reached maximum size, " + ref + " will be dropped");
+         
+         return null;
+      }
+   
+      // Each channel has its own copy of the reference
+      ref = ref.copy();
+
+      try
+      {  
+         if (tx == null)
+         {
+            if (persist && ref.getMessage().isReliable() && recoverable)
+            {
+               // Reliable message in a recoverable state - also add to db
+               if (trace) { log.trace(this + " adding " + ref + " to database non-transactionally"); }
+
+               // TODO - this db access could safely be done outside the event loop
+               pm.addReference(channelID, ref, null);        
+            }
+            
+            // If the ref has a scheduled delivery time then we don't add to the in memory queue
+            // instead we create a timeout, so when that time comes delivery will attempted directly
+            
+            if (!checkAndSchedule(ref))
+            {               
+               synchronized (lock)
+               {
+                  addReferenceInMemory(ref);
+                  
+                  deliverInternal();
+               }            
+            }
+         }
+         else
+         {
+            if (trace) { log.trace(this + " adding " + ref + " to state " + (tx == null ? "non-transactionally" : "in transaction: " + tx)); }
+
+            // add to post commit callback
+            getCallback(tx).addRef(ref);
+            
+            if (trace) { log.trace(this + " added transactionally " + ref + " in memory"); }
+            
+            if (persist && ref.getMessage().isReliable() && recoverable)
+            {
+               // Reliable message in a recoverable state - also add to db
+               if (trace) { log.trace(this + " adding " + ref + (tx == null ? " to database non-transactionally" : " in transaction: " + tx)); }
+
+               pm.addReference(channelID, ref, tx);
+            }
+         }
+         
+         messagesAdded.increment();
+      }
+      catch (Throwable t)
+      {
+         log.error("Failed to handle message", t);
+
+         ref.releaseMemoryReference();
+
+         return null;
+      }
+
+      return new SimpleDelivery(this, ref, true);
+   }
+
+   
+   protected boolean checkAndSchedule(MessageReference ref)
+   {
+      if (ref.getScheduledDeliveryTime() > System.currentTimeMillis())
+      {      
+         if (trace) { log.trace("Scheduling delivery for " + ref + " to occur at " + ref.getScheduledDeliveryTime()); }
+         
+         // Schedule the cancel to actually occur at the specified time. Need to synchronize to
+         // prevent timeout being removed before it is added.
+         synchronized (scheduledDeliveries)
+         {            
+            Timeout timeout =
+               MessagingTimeoutFactory.instance.getFactory().
+                  schedule(ref.getScheduledDeliveryTime(), new DeliverRefTimeoutTarget(ref));
+            
+            scheduledDeliveries.add(timeout);
+         }      
+         
+         return true;
+      }
+      else
+      {
+         return false;
+      }
+   }
+   
+   protected void acknowledgeInternal(Delivery d, Transaction tx, boolean persist) throws Exception
+   {   
+      if (tx == null)
+      {                  
+         if (persist && recoverable && d.getReference().getMessage().isReliable())
+         {
+            pm.removeReference(channelID, d.getReference(), null);
+         }
+              
+         d.getReference().releaseMemoryReference(); 
+                  
+         deliveringCount.decrement();
+      }
+      else
+      {
+         this.getCallback(tx).addDelivery(d);
+   
+         if (trace) { log.trace(this + " added " + d + " to memory on transaction " + tx); }
+   
+         if (recoverable && d.getReference().getMessage().isReliable())
+         {
+            pm.removeReference(channelID, d.getReference(), tx);
+         }
+      }
+   }
+
+   protected InMemoryCallback getCallback(Transaction tx)
+   {
+      InMemoryCallback callback = (InMemoryCallback) tx.getCallback(this);            
+
+      if (callback == null)
+      {
+         callback = new InMemoryCallback();
+
+         tx.addCallback(callback, this);
+      }
+
+      return callback;
+   }
+ 
+   protected MessageReference removeFirstInMemory() throws Exception
+   {
+      MessageReference result = (MessageReference) messageRefs.removeFirst();
+
+      return (MessageReference) result;
+   }
+   
+   protected void addReferenceInMemory(MessageReference ref) throws Exception
+   {
+      messageRefs.addLast(ref, ref.getMessage().getPriority());
+
+      if (trace){ log.trace(this + " added " + ref + " non-transactionally in memory"); }      
+   }    
+   
+   protected boolean getReceiversReady()
+   {
+   	return receiversReady;
+   }
+   
+   protected void setReceiversReady(boolean receiversReady)
+   {
+   	this.receiversReady = receiversReady;
+   }
+   
+   // Private --------------------------------------------------------------------------------------
+      
+   private MessageReference nextReference(ListIterator iter) throws Throwable
+   {
+      MessageReference ref;
+      
+      if (iter == null)
+      {
+         //We just get the next ref from the head of the queue
+         ref = (MessageReference) messageRefs.peekFirst();
+      }
+      else
+      {
+         // TODO This will not work with paged refs - see http://jira.jboss.com/jira/browse/JBMESSAGING-275
+         // We need to extend it to work with refs from the db
+         
+         //We have an iterator - this means we are iterating through the queue to find a ref that matches
+         if (iter.hasNext())
+         {                        
+            ref = (MessageReference)iter.next();
+         } 
+         else
+         {
+            ref = null;
+         }
+      }
+      
+      return ref;
+   } 
+
+   // Inner classes --------------------------------------------------------------------------------
+
+   private class InMemoryCallback implements TxCallback
+   {
+      private List refsToAdd;
+
+      private List deliveriesToRemove;
+      
+      private InMemoryCallback()
+      {
+         refsToAdd = new ArrayList();
+
+         deliveriesToRemove = new ArrayList();
+      }
+      
+      private void addRef(MessageReference ref)
+      {
+         refsToAdd.add(ref);
+      }
+
+      private void addDelivery(Delivery del)
+      {
+         deliveriesToRemove.add(del);
+      }
+
+      public void beforePrepare()
+      {
+         // NOOP
+      }
+
+      public void beforeCommit(boolean onePhase)
+      {
+         // NOOP
+      }
+
+      public void beforeRollback(boolean onePhase)
+      {
+         // NOOP
+      }
+
+      public void afterPrepare()
+      {
+         // NOOP
+      }
+      
+      public void afterCommit(boolean onePhase) throws Exception
+      {         
+         try
+         {
+            // We add the references to the state
+         	
+         	boolean promptDelivery = false;
+            
+            for(Iterator i = refsToAdd.iterator(); i.hasNext(); )
+            {
+               MessageReference ref = (MessageReference)i.next();
+
+               if (trace) { log.trace(this + ": adding " + ref + " to non-recoverable state"); }
+
+               try
+               {
+                  synchronized (lock)
+                  {
+                     addReferenceInMemory(ref);
+                  }
+               }
+               catch (Throwable t)
+               {
+                  throw new TransactionException("Failed to add reference", t);
+               }
+               
+               //Only need to prompt delivery if refs were added
+               promptDelivery = true;
+            }
+
+            // Remove deliveries
+            
+            for(Iterator i = deliveriesToRemove.iterator(); i.hasNext(); )
+            {
+               Delivery del = (Delivery)i.next();
+
+               if (trace) { log.trace(this + " removing " + del + " after commit"); }
+
+               del.getReference().releaseMemoryReference();
+               
+               deliveringCount.decrement();
+            }
+            
+            // prompt delivery
+            if (promptDelivery)
+            {
+            	synchronized (lock)
+            	{
+            		deliverInternal();
+            	}
+            }
+         }
+         catch (Throwable t)
+         {
+            log.error("failed to commit", t);
+            throw new Exception("Failed to commit", t);
+         }
+         
+      }
+
+      public void afterRollback(boolean onePhase) throws Exception
+      {
+         for(Iterator i = refsToAdd.iterator(); i.hasNext(); )
+         {
+            MessageReference ref = (MessageReference)i.next();
+
+            if (trace) { log.trace(this + " releasing memory " + ref + " after rollback"); }
+            ref.releaseMemoryReference();
+         }
+      }
+
+      public String toString()
+      {
+         return ChannelSupport.this + ".InMemoryCallback[" +
+                Integer.toHexString(InMemoryCallback.this.hashCode()) + "]";
+      }
+   }
+
+   /**
+    * Give subclass a chance to process the message before storing it internally.
+    * TODO - Do we really need this?
+    */
+   protected void processMessageBeforeStorage(MessageReference reference)
+   {
+      // by default a noop
+   }
+
+   protected void checkClosed()
+   {
+      if (distributor == null)
+      {
+         throw new IllegalStateException(this + " closed");
+      }
+   }
+
+   // Private --------------------------------------------------------------------------------------
+   
+   // Inner classes --------------------------------------------------------------------------------
+      
+   private class DeliverRefTimeoutTarget implements TimeoutTarget
+   {
+      private MessageReference ref;
+
+      public DeliverRefTimeoutTarget(MessageReference ref)
+      {
+         this.ref = ref;
+      }
+
+      public void timedOut(Timeout timeout)
+      {
+         if (trace) { log.trace("Scheduled delivery timeout " + ref); }
+         
+         synchronized (scheduledDeliveries)
+         {
+            boolean removed = scheduledDeliveries.remove(timeout);
+            
+            if (!removed)
+            {
+               throw new IllegalStateException("Failed to remove timeout " + timeout);
+            }
+         }
+              
+         ref.setScheduledDeliveryTime(0);
+         
+         boolean delivered = false;
+         
+         if (distributor.getNumberOfReceivers() > 0)
+         {               
+            delivered = deliverScheduled(ref);     
+         }
+
+         if (!delivered)
+         {
+            try
+            {
+               cancelInternal(ref);
+            }
+            catch (Exception e)
+            {
+               log.error("Failed to cancel", e);
+            }
+         }
+         else
+         {
+            if (trace) { log.trace("Delivered scheduled delivery at " + System.currentTimeMillis() + " for " + ref); }
+         }
+      }
+   }
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/ClusterRoundRobinDistributor.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/ClusterRoundRobinDistributor.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/ClusterRoundRobinDistributor.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,182 @@
+/*
+  * 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.impl;
+
+import java.util.Iterator;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.DeliveryObserver;
+import org.jboss.messaging.core.contract.Distributor;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.Receiver;
+import org.jboss.messaging.core.impl.tx.Transaction;
+
+/**
+ *  
+ * This distributor is used when distributing to consumers of clustered queues.
+ * 
+ * It maintains two round robin distributors - one corresponding to the remote receivers and one corresponding to the local receivers
+ * 
+ * The local receivers always take priority over the remote receivers
+ *  
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1 $</tt>
+ * $Id: $
+ */
+public class ClusterRoundRobinDistributor implements Distributor
+{
+   // Constants ------------------------------------------------------------------------------------
+	
+   private static final Logger log = Logger.getLogger(ClusterRoundRobinDistributor.class);
+	
+   // Static ---------------------------------------------------------------------------------------
+   
+   // Attributes -----------------------------------------------------------------------------------
+   
+   private Distributor localDistributor;
+   
+   private Distributor remoteDistributor;
+   
+   private boolean preserveOrdering;
+   
+   // Constructors ---------------------------------------------------------------------------------
+
+   public ClusterRoundRobinDistributor(Distributor local, Distributor remote, boolean preserveOrdering)
+   {
+      localDistributor = local;
+      
+      remoteDistributor = remote;
+   }
+
+   // Distributor implementation ------------------------------------------------------------------------
+   
+   public Delivery handle(DeliveryObserver observer, MessageReference ref, Transaction tx)
+   {             
+      //First try the local distributor
+   	
+   	log.info("** first trying with local distributor");
+   	
+   	Delivery del = localDistributor.handle(observer, ref, tx);
+   	
+   	log.info("*** local distributor returned " + del);
+   	
+   	if (del == null)
+   	{
+   		//If no local distributor takes the ref then we try the remote distributor
+   		
+   		log.info("** preserve ordering is " + preserveOrdering);
+   		
+   		if (preserveOrdering)
+   		{
+   			if (ref.getMessage().getHeader(Message.CLUSTER_SUCKED) != null)
+   			{
+   				//The message has already been sucked once - don't suck it again
+   				
+   				return null;
+   			}
+   			else
+   			{
+   				//Add the header - so it doesn't get sucked more than once
+   				
+   				ref.getMessage().putHeader(Message.CLUSTER_SUCKED, new Integer(333));
+   			}
+   		}
+   		
+   		log.info("*** sending to remote distributor");
+   		
+   		del = remoteDistributor.handle(observer, ref, tx);
+   		
+   		log.info("** remote distributor returned " + del);
+   	}
+   	
+   	return del;
+   }
+   
+   public synchronized boolean add(Receiver r)
+   {            
+   	//FIXME - get the absraction right so this is not necessary
+      throw new IllegalStateException("Not used!");     
+   }
+
+   public synchronized boolean remove(Receiver r)
+   {      
+   	//FIXME - get the absraction right so this is not necessary
+      throw new java.lang.IllegalStateException("Not used!"); 
+   }
+   
+   public synchronized void clear()
+   {
+      localDistributor.clear();
+      
+      remoteDistributor.clear(); 
+   }
+
+   public synchronized boolean contains(Receiver r)
+   {
+      return localDistributor.contains(r) || remoteDistributor.contains(r);     
+   }
+
+   public synchronized Iterator iterator()
+   {
+   	//We only count the local ones
+      return localDistributor.iterator();      
+   }
+   
+   public synchronized int getNumberOfReceivers()
+   {
+      return localDistributor.getNumberOfReceivers() + remoteDistributor.getNumberOfReceivers();
+   }
+
+   // Public ---------------------------------------------------------------------------------------
+   
+   public void addLocal(Receiver r)
+   {
+   	localDistributor.add(r);
+   }
+   
+   public boolean removeLocal(Receiver r)
+   {
+   	return localDistributor.remove(r);
+   }
+   
+   public void addRemote(Receiver r)
+   {
+   	remoteDistributor.add(r);
+   }
+   
+   public boolean removeRemote(Receiver r)
+   {
+   	return remoteDistributor.remove(r);
+   }
+
+   // Package protected ----------------------------------------------------------------------------
+   
+   // Protected ------------------------------------------------------------------------------------
+
+   // Private --------------------------------------------------------------------------------------
+   
+   
+   // Inner classes --------------------------------------------------------------------------------
+}
+

Added: trunk/src/main/org/jboss/messaging/core/impl/DefaultClusterNotifier.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/DefaultClusterNotifier.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/DefaultClusterNotifier.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,81 @@
+/*
+  * 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.impl;
+
+import java.util.Iterator;
+import java.util.Set;
+
+import org.jboss.messaging.core.contract.ClusterNotification;
+import org.jboss.messaging.core.contract.ClusterNotificationListener;
+import org.jboss.messaging.core.contract.ClusterNotifier;
+import org.jboss.messaging.util.ConcurrentReaderHashSet;
+
+
+/**
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: $</tt>21 Jun 2007
+ *
+ * $Id: $
+ *
+ */
+public class DefaultClusterNotifier implements ClusterNotifier
+{
+	private Set listeners;
+	
+	public DefaultClusterNotifier()
+	{
+		listeners = new ConcurrentReaderHashSet();
+	}
+
+	public void registerListener(ClusterNotificationListener listener)
+	{
+		if (listeners.contains(listener))
+		{
+			throw new IllegalStateException("Listener " + listener + " is already registered");
+		}
+		
+		listeners.add(listener);
+	}
+
+	public void sendNotification(ClusterNotification notification)
+	{
+		Iterator iter = listeners.iterator();
+		
+		while (iter.hasNext())
+		{
+			ClusterNotificationListener listener = (ClusterNotificationListener)iter.next();
+			
+			listener.notify(notification);
+		}
+	}
+
+	public void unregisterListener(ClusterNotificationListener listener)
+	{
+		if (!listeners.remove(listener))
+		{
+			throw new IllegalStateException("Listener " + listener + " is not registered");		
+		}
+	}
+
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/FailoverWaiter.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/FailoverWaiter.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/FailoverWaiter.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,174 @@
+/*
+ * 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.impl;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.contract.ClusterNotification;
+import org.jboss.messaging.core.contract.ClusterNotificationListener;
+import org.jboss.messaging.core.impl.tx.TransactionRepository;
+
+/**
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: $</tt>22 Jun 2007
+ *
+ * $Id: $
+ *
+ */
+public class FailoverWaiter implements ClusterNotificationListener
+{
+   private static final Logger log = Logger.getLogger(FailoverWaiter.class);
+	
+	private int failingOverFor;
+	
+	private int failedOverFor;
+	
+   private Object failoverStatusLock;
+   
+   private long failoverStartTimeout;
+   
+   private long failoverCompleteTimeout;
+   
+   private int nodeID;
+     
+   private TransactionRepository txRepository;
+   
+   public FailoverWaiter(int nodeID, long failoverStartTimeout, long failoverCompleteTimeout,
+   		                TransactionRepository txRepository)
+   {
+      failoverStatusLock = new Object();
+      
+      this.nodeID = nodeID;
+      
+      this.failoverStartTimeout = failoverStartTimeout;
+      
+      this.failoverCompleteTimeout = failoverCompleteTimeout;
+      
+      this.txRepository = txRepository;
+   }
+   
+   /*
+    * Wait for failover from the specified node to complete.
+    */
+   public int waitForFailover(int failedNodeID) throws Exception
+   {
+      // This node may be failing over for another node - in which case we must wait for that to be
+      // complete.
+   	
+   	// TODO deal with multiple failover cascades
+   	
+   	//First wait for failover to start
+   	synchronized (failoverStatusLock)
+   	{
+         long startToWait = failoverStartTimeout;
+            		
+   		while (startToWait > 0 && failingOverFor != failedNodeID && failedOverFor != failedNodeID)
+   		{
+   			long start = System.currentTimeMillis(); 
+            try
+            {
+               log.debug(this + " blocking on the failover lock, waiting for failover to start");
+               failoverStatusLock.wait(startToWait);
+               log.debug(this + " releasing the failover lock, checking again whether failover started ...");
+            }
+            catch (InterruptedException ignore)
+            {                  
+            }
+            startToWait -= System.currentTimeMillis() - start;  
+   		}
+   		
+   		if (failingOverFor != failedNodeID && failedOverFor != failedNodeID)
+   		{
+   			//Timed out
+   			log.debug("Timed out waiting for failover to start");
+   			
+   			return -1;
+   		}
+   	}
+   	
+   	//Wait for failover to complete
+   	synchronized (failoverStatusLock)
+   	{
+   		long completeToWait = failoverCompleteTimeout;
+   		
+   		while (completeToWait > 0 && failedOverFor != failedNodeID)
+   		{
+   			long start = System.currentTimeMillis(); 
+            try
+            {
+               log.debug(this + " blocking on the failover lock, waiting for failover to complete");
+               failoverStatusLock.wait(completeToWait);
+               log.debug(this + " releasing the failover lock, checking again whether failover completed ...");
+            }
+            catch (InterruptedException ignore)
+            {                  
+            }
+            completeToWait -= System.currentTimeMillis() - start;  
+   		}
+   		
+   		if (failedOverFor != failedNodeID)
+   		{
+   			//Timed out
+   			log.debug("Timed out waiting for failover to complete");
+   			
+   			return -1;
+   		}
+   	}
+   	
+   	return nodeID;
+   }
+
+	public void notify(ClusterNotification notification)
+	{
+		if (notification.type == ClusterNotification.TYPE_FAILOVER_START)
+		{
+			synchronized (failoverStatusLock)
+			{
+				failingOverFor = notification.nodeID;
+
+				failoverStatusLock.notifyAll();
+			}
+		}
+		else if (notification.type == ClusterNotification.TYPE_FAILOVER_END)
+		{
+			//	We prompt txRepository to load any prepared txs - so we can take over
+			// responsibility for in doubt transactions from other nodes
+			try
+			{
+				txRepository.loadPreparedTransactions();
+			}
+			catch (Exception e)
+			{
+				log.error("Failed to load prepared transactions", e);
+			}
+
+			synchronized (failoverStatusLock)
+			{									
+				failedOverFor = failingOverFor;
+
+				failingOverFor = -1;
+
+				failoverStatusLock.notifyAll();
+			}
+		}
+	}	
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/FirstReceiverDistributor.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/FirstReceiverDistributor.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/FirstReceiverDistributor.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,196 @@
+/*
+  * 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.impl;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.DeliveryObserver;
+import org.jboss.messaging.core.contract.Distributor;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.Receiver;
+import org.jboss.messaging.core.impl.tx.Transaction;
+
+/**
+ * 
+ * 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)
+ * then if the consumers are fast then the first receiver will tend to get most or all of the references
+ * 
+ * @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: 1174 $</tt>
+ * $Id: PointToPointRouter.java 1174 2006-08-02 14:14:32Z timfox $
+ */
+public class FirstReceiverDistributor implements Distributor
+{
+   // Constants -----------------------------------------------------
+
+   private static final Logger log = Logger.getLogger(FirstReceiverDistributor.class);
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   private boolean trace = log.isTraceEnabled();
+
+   private List receivers;
+   
+   private volatile boolean makeCopy;
+   
+   private ArrayList receiversCopy;
+
+   // Constructors --------------------------------------------------
+
+   public FirstReceiverDistributor()
+   {
+      receivers = new ArrayList();
+      
+      makeCopy = true;
+   }
+
+   // Router implementation -----------------------------------------
+
+   public Delivery handle(DeliveryObserver observer, MessageReference ref, Transaction tx)
+   {
+      if (makeCopy)
+      {
+         synchronized (this)
+         {         
+            //We make a copy of the receivers to avoid a race condition:
+            //http://jira.jboss.org/jira/browse/JBMESSAGING-505
+            //Note that we do not make a copy every time - only when the receivers have changed
+         
+            receiversCopy = new ArrayList(receivers);
+            
+            makeCopy = false;
+         }
+      }    
+      
+      Delivery del = null;
+      
+      boolean selectorRejected = false;
+
+      for(Iterator i = receiversCopy.iterator(); i.hasNext(); )
+      {
+         Receiver receiver = (Receiver)i.next();
+
+         try
+         {
+            Delivery d = receiver.handle(observer, ref, tx);
+
+            if (trace) { log.trace("receiver " + receiver + " handled " + ref + " and returned " + d); }
+
+            if (d != null)
+            {
+               if (d.isSelectorAccepted())
+               {
+                  // deliver to the first receiver that accepts
+                  del = d;
+                  break;
+               }
+               else
+               {
+                  selectorRejected = true;
+               }
+            }
+         }
+         catch(Throwable t)
+         {
+            // broken receiver - log the exception and ignore it
+            log.error("The receiver " + receiver + " is broken", t);
+         }
+      }
+
+      if (del == null && selectorRejected)
+      {
+         del = new SimpleDelivery(null, null, false);
+      }
+
+      return del;
+   }
+
+
+   public synchronized boolean add(Receiver r)
+   {
+      if (receivers.contains(r))
+      {
+         return false;
+      }
+      
+      receivers.add(r);
+      
+      makeCopy = true;
+      
+      return true;
+   }
+
+
+   public synchronized boolean remove(Receiver r)
+   {            
+      boolean removed = receivers.remove(r);      
+      
+      if (removed)
+      {
+         makeCopy = true;
+      }
+      
+      return removed;
+   }
+
+   public synchronized void clear()
+   {
+      receivers.clear();
+      
+      makeCopy = true;
+   }
+
+   public synchronized boolean contains(Receiver r)
+   {
+      return receivers.contains(r);      
+   }
+
+   public synchronized Iterator iterator()
+   {
+      return receivers.iterator();      
+   }
+   
+   public synchronized int getNumberOfReceivers()
+   {
+      return receivers.size();      
+   }
+
+
+   // Public --------------------------------------------------------
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------   
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/IDManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/IDManager.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/IDManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,139 @@
+/*
+  * 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.impl;
+
+import org.jboss.jms.delegate.IDBlock;
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.contract.MessagingComponent;
+import org.jboss.messaging.core.contract.PersistenceManager;
+
+/**
+ * 
+ * A IDManager.
+ * 
+ * @author <a href="tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @version <tt>$Revision: 2686 $</tt>
+ *
+ * $Id: IDManager.java 2686 2007-05-15 08:47:20Z timfox $
+ */
+public class IDManager implements MessagingComponent
+{
+   // Constants -----------------------------------------------------
+
+   private static final Logger log = Logger.getLogger(IDManager.class);
+
+   // Static --------------------------------------------------------
+
+   // Attributes ----------------------------------------------------
+
+   private boolean trace = log.isTraceEnabled();
+
+   private boolean started;
+
+   private String counterName;
+
+   private int bigBlockSize;
+   private long high;
+   private long low;
+
+   private PersistenceManager pm;
+
+   // Constructors --------------------------------------------------
+
+   public IDManager(String counterName, int bigBlockSize, PersistenceManager pm) throws Exception
+   {
+      this.counterName = counterName;
+      this.bigBlockSize = bigBlockSize;
+      this.pm = pm;
+   }
+
+   // MessagingComponent implementation -----------------------------
+
+   public synchronized void start() throws Exception
+   {
+      getNextBigBlock();
+      started = true;
+   }
+
+   public synchronized void stop() throws Exception
+   {
+      started = false;
+   }
+
+   // Public --------------------------------------------------------
+
+   protected void getNextBigBlock() throws Exception
+   {
+      low = pm.reserveIDBlock(counterName, bigBlockSize);
+      high = low + bigBlockSize - 1;
+      if (trace) { log.trace(this + " retrieved next block of size " + bigBlockSize + " from PersistenceManager, starting at " + low); }
+   }
+
+   public synchronized IDBlock getIDBlock(int size) throws Exception
+   {
+      if (!started)
+      {
+         throw new IllegalStateException(this + " is not started");
+      }
+
+      if (size <= 0)
+      {
+         throw new IllegalArgumentException("block size must be > 0");
+      }
+
+      if (size > bigBlockSize)
+      {
+         throw new IllegalArgumentException("block size must be <= bigBlockSize");
+      }
+
+      if (size > high - low + 1)
+      {
+         getNextBigBlock();
+      }
+
+      long low = this.low;
+
+      this.low += size;
+
+      return new IDBlock(low, this.low - 1);
+   }
+
+   public synchronized long getID() throws Exception
+   {
+      return getIDBlock(1).getLow();
+   }
+
+   public String toString()
+   {
+      return "IDManager[" + counterName + ", " + low + "-" + high + "]";
+   }
+
+   // Package protected ---------------------------------------------
+
+   // Protected -----------------------------------------------------
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/JDBCPersistenceManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/JDBCPersistenceManager.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/JDBCPersistenceManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,3175 @@
+/*
+ * 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.impl;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.InputStream;
+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.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.sql.DataSource;
+import javax.transaction.TransactionManager;
+import javax.transaction.xa.Xid;
+
+import org.jboss.jms.tx.MessagingXid;
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.PersistenceManager;
+import org.jboss.messaging.core.impl.message.MessageFactory;
+import org.jboss.messaging.core.impl.message.MessageSupport;
+import org.jboss.messaging.core.impl.tx.PreparedTxInfo;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.core.impl.tx.TxCallback;
+import org.jboss.messaging.util.JDBCUtil;
+import org.jboss.messaging.util.LockMap;
+import org.jboss.messaging.util.StreamUtils;
+import org.jboss.messaging.util.Util;
+
+/**
+ * JDBC implementation of PersistenceManager.
+ *  
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
+ * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
+ *
+ * @version <tt>1.1</tt>
+ *
+ * JDBCPersistenceManager.java,v 1.1 2006/02/22 17:33:41 timfox Exp
+ */
+public class JDBCPersistenceManager extends JDBCSupport implements PersistenceManager
+{
+   // Constants -----------------------------------------------------
+   
+   private static final Logger log = Logger.getLogger(JDBCPersistenceManager.class); 
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   private boolean trace = log.isTraceEnabled();
+      
+   private boolean usingBatchUpdates = false;
+   
+   private boolean usingBinaryStream = true;
+   
+   private boolean usingTrailingByte = false;
+   
+   private int maxParams;
+   
+   private short orderCount;
+   
+   
+   // Constructors --------------------------------------------------
+    
+   public JDBCPersistenceManager(DataSource ds, TransactionManager tm, Properties sqlProperties,
+                                 boolean createTablesOnStartup, boolean usingBatchUpdates,
+                                 boolean usingBinaryStream, boolean usingTrailingByte, int maxParams)
+   {
+      super(ds, tm, sqlProperties, createTablesOnStartup);
+      
+      this.usingBatchUpdates = usingBatchUpdates;
+      
+      this.usingBinaryStream = usingBinaryStream;
+      
+      this.usingTrailingByte = usingTrailingByte;
+      
+      this.maxParams = maxParams;      
+   }
+   
+   
+   // MessagingComponent overrides ---------------------------------
+   
+   public void start() throws Exception
+   {
+      super.start();
+
+      Connection conn = null;
+
+      TransactionWrapper wrap = new TransactionWrapper();
+
+      try
+      {
+         conn = ds.getConnection();      
+         //JBossMessaging requires transaction isolation of READ_COMMITTED
+         //Any looser isolation level and we cannot maintain consistency for paging (HSQL)
+         if (conn.getTransactionIsolation() != Connection.TRANSACTION_READ_COMMITTED)
+         {
+            int level = conn.getTransactionIsolation();
+
+            String warn =
+               "\n\n" +
+               "JBoss Messaging Warning: DataSource connection transaction isolation should be READ_COMMITTED, but it is currently " + Util.transactionIsolationToString(level) + ".\n" +
+               "                         Using an isolation level less strict than READ_COMMITTED may lead to data consistency problems.\n" +
+               "                         Using an isolation level more strict than READ_COMMITTED may lead to deadlock.\n";
+            log.warn(warn);
+         }
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+         if (conn != null)
+         {
+            conn.close();
+         }
+         wrap.end();
+      }
+             
+      log.debug(this + " started");
+   }
+   
+   public void stop() throws Exception
+   {
+      super.stop();
+   }
+   
+   // PersistenceManager implementation -------------------------
+   
+   // Related to XA Recovery
+   // ======================
+   
+   public List getMessageChannelPairRefsForTx(long transactionId) throws Exception
+   {
+      String sql = this.getSQLStatement("SELECT_MESSAGE_ID_FOR_REF");
+      return getMessageChannelPair(sql, transactionId);
+   }
+   
+   public List getMessageChannelPairAcksForTx(long transactionId) throws Exception
+   {
+      String sql = this.getSQLStatement("SELECT_MESSAGE_ID_FOR_ACK");
+      return getMessageChannelPair(sql, transactionId);
+   }
+   
+   public List retrievePreparedTransactions() throws Exception
+   {
+      /* Note the API change for 1.0.2 XA Recovery -- List now contains instances of PreparedTxInfo<TxId, Xid>
+       * instead of direct Xids [JPL] */
+      
+      Connection conn = null;
+      Statement st = null;
+      ResultSet rs = null;
+      PreparedTxInfo txInfo = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      try
+      {
+         List transactions = new ArrayList();
+         
+         conn = ds.getConnection();
+         
+         st = conn.createStatement();
+         
+         String sql = this.getSQLStatement("SELECT_PREPARED_TRANSACTIONS");
+         
+         rs = st.executeQuery(sql);
+         
+         while (rs.next())
+         {
+            //get the existing tx id --MK START
+            long txId = rs.getLong(1);
+            
+            byte[] branchQual = getVarBinaryColumn(rs, 2);
+            
+            int formatId = rs.getInt(3);
+            
+            byte[] globalTxId = getVarBinaryColumn(rs, 4);
+            
+            Xid xid = new MessagingXid(branchQual, formatId, globalTxId);
+            
+            // create a tx info object with the result set detailsdetails
+            txInfo = new PreparedTxInfo(txId, xid);
+            
+            transactions.add(txInfo);
+         }
+         
+         return transactions;
+         
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+      	closeResultSet(rs);
+      	closeStatement(st);
+      	closeConnection(conn);
+         wrap.end();
+      }
+   }
+         
+               
+   // Related to counters
+   // ===================
+   
+   public long reserveIDBlock(String counterName, int size) throws Exception
+   {
+      if (trace) { log.trace("Getting ID block for counter " + counterName + ", size " + size); }
+      
+      if (size <= 0)
+      {
+         throw new IllegalArgumentException("block size must be > 0");
+      }
+      
+      Connection conn = null;
+      PreparedStatement ps = null;
+      ResultSet rs = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      try
+      {
+         conn = ds.getConnection();
+
+         //For the clustered case - this MUST use SELECT .. FOR UPDATE or a similar
+         //construct the locks the row
+         String selectCounterSQL = getSQLStatement("SELECT_COUNTER");
+         
+         ps = conn.prepareStatement(selectCounterSQL);
+         
+         ps.setString(1, counterName);
+         
+         rs = ps.executeQuery();
+         
+         if (trace) { log.trace(JDBCUtil.statementToString(selectCounterSQL, counterName)); }         
+         
+         if (!rs.next())
+         {
+            rs.close();
+            rs = null;
+            
+            ps.close();
+            
+            //There is a very small possibility that two threads will attempt to insert the same counter
+            //at the same time, if so, then the second one will fail eventually after a few retries by throwing
+            //a primary key violation.
+            
+            String insertCounterSQL = getSQLStatement("INSERT_COUNTER");
+            
+            ps = conn.prepareStatement(insertCounterSQL);
+            
+            ps.setString(1, counterName);
+            ps.setLong(2, size);
+            
+            int rows = updateWithRetry(ps);
+            if (trace) { log.trace(JDBCUtil.statementToString(insertCounterSQL, counterName, new Integer(size)) + " inserted " + rows + " rows"); }
+            
+            ps.close();            
+            ps = null;
+            return 0;
+         }
+         
+         long nextId = rs.getLong(1);
+         
+         rs.close();
+         rs = null;
+         
+         ps.close();
+
+         String updateCounterSQL = getSQLStatement("UPDATE_COUNTER");
+
+         ps = conn.prepareStatement(updateCounterSQL);
+         
+         ps.setLong(1, nextId + size);
+         ps.setString(2, counterName);
+         
+         int rows = updateWithRetry(ps);
+         if (trace) { log.trace(JDBCUtil.statementToString(updateCounterSQL, new Long(nextId + size), counterName) + " updated " + rows + " rows"); }
+         
+         return nextId;
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+      	closeStatement(ps);
+      	closeConnection(conn);
+         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
+    * with a maximum of 100 elements.
+    * If there are more than maxParams message to retrieve this is repeated a number of times.
+    * For "Enterprise" databases (Oracle, DB2, Sybase etc) a more sophisticated technique should be used
+    * e.g. Oracle ARRAY types in Oracle which can be submitted as a param to an Oracle prepared statement
+    * Although this would all be DB specific.
+    */
+   public List getMessages(List messageIds) throws Exception
+   {
+      if (trace) { log.trace("Getting batch of messages for " + messageIds); }
+      
+      Connection conn = null;
+      PreparedStatement ps = null;
+      ResultSet rs = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      try
+      {
+         conn = ds.getConnection();
+         
+         Iterator iter = messageIds.iterator();
+         
+         int size = messageIds.size();
+         
+         int count = 0;
+         
+         List msgs = new ArrayList();
+         
+         while (iter.hasNext())
+         {
+            if (ps == null)
+            {
+               //PreparedStatements are cached in the JCA layer so we will never actually have more than
+               //100 distinct ones            
+               int numParams;
+               if (count < (size / maxParams) * maxParams)
+               {
+                  numParams = maxParams;
+               }
+               else
+               {
+                  numParams = size % maxParams;
+               }
+               StringBuffer buff = new StringBuffer(getSQLStatement("LOAD_MESSAGES"));
+               buff.append(" WHERE ").append(getSQLStatement("MESSAGE_ID_COLUMN")).append(" IN (");
+               for (int i = 0; i < numParams; i++)
+               {
+                  buff.append("?");
+                  if (i < numParams - 1)
+                  {
+                     buff.append(",");
+                  }
+               }
+               buff.append(")");
+               ps = conn.prepareStatement(buff.toString());
+               
+               if (trace)
+               {
+                  log.trace(buff.toString());
+               }
+            }
+            
+            long msgId = ((Long)iter.next()).longValue();
+            
+            ps.setLong((count % maxParams) + 1, msgId);
+            
+            count++;
+            
+            if (!iter.hasNext() || count % maxParams == 0)
+            {
+               rs = ps.executeQuery();
+               
+               while (rs.next())
+               {       
+                  long messageId = rs.getLong(1);
+                  
+                  boolean reliable = rs.getString(2).equals("Y");
+                  
+                  long expiration = rs.getLong(3);
+                  
+                  long timestamp = rs.getLong(4);
+                  
+                  byte priority = rs.getByte(5);        
+                  
+                  byte[] bytes = getBytes(rs, 6);
+                  
+                  HashMap headers = bytesToMap(bytes);
+                  
+                  byte[] payload = getBytes(rs, 7);
+                  
+                  byte type = rs.getByte(8);
+                  
+                  Message m = MessageFactory.createMessage(messageId, reliable, expiration, timestamp, priority,
+                                                           headers, payload, type);
+                  msgs.add(m);
+               }
+               
+               rs.close();
+               rs = null;
+               
+               ps.close();
+               ps = null;
+            }
+         }
+         
+         if (trace) { log.trace("Loaded " + msgs.size() + " messages in total"); }
+
+         return msgs;
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+      	closeResultSet(rs);
+      	closeStatement(ps);
+      	closeConnection(conn);
+         wrap.end();
+      }
+   }  
+   
+       
+   // Related to paging functionality
+   // ===============================                 
+   
+   public void pageReferences(long channelID, List references, boolean paged) throws Exception
+   {  
+      Connection conn = null;
+      PreparedStatement psInsertReference = null;  
+      PreparedStatement psInsertMessage = null;
+      PreparedStatement psUpdateMessage = null;
+      PreparedStatement psMessageExists = null;
+      ResultSet rsMessageExists = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+            
+      //First we order the references in message order
+      orderReferences(references);
+                         
+      try
+      {
+         //Now we get a lock on all the messages. Since we have ordered the refs we should avoid deadlock
+         getLocks(references);
+         
+         conn = ds.getConnection();
+         
+         Iterator iter = references.iterator();
+         
+         boolean messageInsertsInBatch = false;
+         boolean messageUpdatesInBatch = false;
+         
+         if (usingBatchUpdates)
+         {
+            psInsertReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
+            psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+            psUpdateMessage = conn.prepareStatement(getSQLStatement("INC_CHANNEL_COUNT"));
+         }
+         
+         while (iter.hasNext())
+         {
+            //We may need to persist the message itself 
+            MessageReference ref = (MessageReference) iter.next();
+                                            
+            //For non reliable refs we insert the ref (and maybe the message) itself
+                           
+            if (!usingBatchUpdates)
+            {
+               psInsertReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
+            }
+            
+            //Now store the reference
+            addReference(channelID, ref, psInsertReference, paged);
+                        
+            if (usingBatchUpdates)
+            {
+               psInsertReference.addBatch();
+            }
+            else
+            {
+               int rows = updateWithRetry(psInsertReference);
+               
+               if (trace)
+               {
+                  log.trace("Inserted " + rows + " rows");
+               }
+               
+               psInsertReference.close();
+               psInsertReference = null;
+            }
+            
+            if (!usingBatchUpdates)
+            {
+               psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+               psUpdateMessage = conn.prepareStatement(getSQLStatement("INC_CHANNEL_COUNT"));
+            }
+                                                                                     
+            //Maybe we need to persist the message itself
+            Message m = ref.getMessage();
+            
+            //In a paging situation, we cannot use the persisted flag on the message to determine whether
+            //to insert the message or not.
+            //This is because a channel (possibly on another node) may be paging too and referencing
+            //the same message, and might have removed the message independently, the other
+            //channel will not know about this.
+            //Therefore we have to check if the message is already in the database and insert it if it isn't
+            
+            //TODO This is a bit of a hassle -
+            //A cleaner and better solution here is to completely separate out the paging functionality from the
+            //standard persistence functionality since it complicates things considerably.
+            //We should define a paging store which is separate from the persistence store, and
+            //typically not using the database for the paging store - probably use a file based store
+            //e.g HOWL or some other logger
+            
+            //Note when running this with two or more competing channels in the same process, then
+            //we do not need a FOR UPDATE on the select since we lock the messages in memory
+            //However for competing nodes, we do, therefore we require a database that supports
+            //this, this is another reason why we cannot use HSQL in a clustered environment
+            //since it does not have a for update equivalent
+            
+            boolean added;
+            
+            psMessageExists = conn.prepareStatement(getSQLStatement("MESSAGE_EXISTS"));
+            
+            psMessageExists.setLong(1, m.getMessageID());
+            
+            rsMessageExists = psMessageExists.executeQuery();
+             
+            if (rsMessageExists.next())
+            {
+               //Message exists
+               
+               // Update the message with the new channel count
+               incrementChannelCount(m, psUpdateMessage);
+                  
+               added = false;              
+            }
+            else
+            {
+               //Hasn't been persisted before so need to persist the message
+               storeMessage(m, psInsertMessage);
+               
+               added = true;
+            }    
+            
+            if (usingBatchUpdates)
+            {
+               if (added)
+               {
+                  psInsertMessage.addBatch();
+                  messageInsertsInBatch = true;
+               }
+               else
+               {
+                  psUpdateMessage.addBatch();
+                  messageUpdatesInBatch = true;
+               }
+            }
+            else
+            {
+               if (added)
+               {
+                  int rows = updateWithRetry(psInsertMessage);
+                                      
+                  if (trace)
+                  {
+                     log.trace("Inserted " + rows + " rows");
+                  }
+               }
+               else
+               {               
+                  int rows = updateWithRetry(psUpdateMessage);
+                  
+                  if (trace)
+                  {
+                     log.trace("Updated " + rows + " rows");
+                  }
+               }
+               psInsertMessage.close();
+               psInsertMessage = null;
+               psUpdateMessage.close();
+               psUpdateMessage = null;
+            }      
+         }         
+         
+         if (usingBatchUpdates)
+         {
+            int[] rowsReference = updateWithRetryBatch(psInsertReference);
+            
+            if (trace) { logBatchUpdate(getSQLStatement("INSERT_MESSAGE_REF"), rowsReference, "inserted"); }
+            
+            if (messageInsertsInBatch)
+            {
+               int[] rowsMessage = updateWithRetryBatch(psInsertMessage);
+               
+               if (trace) { logBatchUpdate(getSQLStatement("INSERT_MESSAGE"), rowsMessage, "inserted"); }
+            }
+            if (messageUpdatesInBatch)
+            {
+               int[] rowsMessage = updateWithRetryBatch(psUpdateMessage);
+               
+               if (trace) { logBatchUpdate(getSQLStatement("INC_CHANNEL_COUNT"), rowsMessage, "updated"); }
+            }
+            
+            psInsertReference.close();
+            psInsertReference = null;
+            psInsertMessage.close();
+            psInsertMessage = null;
+            psUpdateMessage.close();
+            psUpdateMessage = null;
+         }        
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+      	closeStatement(psInsertReference);
+      	closeStatement(psInsertMessage);
+      	closeStatement(psUpdateMessage);
+      	closeConnection(conn);         
+         try
+         {
+            wrap.end();                       
+         }
+         finally
+         {            
+            //And then release locks
+            this.releaseLocks(references);
+         }         
+      }      
+   }
+         
+   public void removeDepagedReferences(long channelID, List references) throws Exception
+   {
+      if (trace) { log.trace(this + " Removing " + references.size() + " refs from channel " + channelID); }
+          
+      Connection conn = null;
+      PreparedStatement psDeleteReference = null;  
+      PreparedStatement psDeleteMessage = null;
+      PreparedStatement psUpdateMessage = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+        
+      //We order the references
+      orderReferences(references);
+             
+      try
+      {
+         //We get locks on all the messages - since they are ordered we avoid deadlock
+         getLocks(references);
+         
+         conn = ds.getConnection();
+         
+         Iterator iter = references.iterator();
+         
+         if (usingBatchUpdates)
+         {
+            psDeleteReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
+            psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+            psUpdateMessage = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
+         }
+         
+         while (iter.hasNext())
+         {
+            MessageReference ref = (MessageReference) iter.next();
+                                                             
+            if (!usingBatchUpdates)
+            {
+               psDeleteReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
+            }
+            
+            removeReference(channelID, ref, psDeleteReference);
+            
+            if (usingBatchUpdates)
+            {
+               psDeleteReference.addBatch();
+            }
+            else
+            {
+               int rows = updateWithRetry(psDeleteReference);
+               
+               if (trace) { log.trace("Deleted " + rows + " rows"); }
+               
+               psDeleteReference.close();
+               psDeleteReference = null;
+            }
+            
+            if (!usingBatchUpdates)
+            {
+               psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+               psUpdateMessage = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
+            }
+               
+            Message m = ref.getMessage();
+                                    
+            //Maybe we need to delete the message itself
+              
+            //Update the message with the new channel count
+            decrementChannelCount(m, psUpdateMessage);
+            
+
+            //Run the remove message update
+            removeMessage(m, psDeleteMessage);
+                        
+            if (usingBatchUpdates)
+            {
+               psUpdateMessage.addBatch();
+               
+               psDeleteMessage.addBatch();
+            }
+            else
+            {  
+               int rows = updateWithRetry(psUpdateMessage);
+                                                 
+               if (trace) { log.trace("Updated " + rows + " rows"); }
+               
+               rows = updateWithRetry(psDeleteMessage);
+        
+               if (trace) { log.trace("Deleted " + rows + " rows"); }
+            
+               psDeleteMessage.close();
+               psDeleteMessage = null;
+               psUpdateMessage.close();
+               psUpdateMessage = null;
+            }  
+            
+         }         
+         
+         if (usingBatchUpdates)
+         {
+            int[] rowsReference = updateWithRetryBatch(psDeleteReference);
+            
+            if (trace) { logBatchUpdate(getSQLStatement("DELETE_MESSAGE_REF"), rowsReference, "deleted"); }
+            
+            rowsReference = updateWithRetryBatch(psUpdateMessage);
+            
+            if (trace) { logBatchUpdate(getSQLStatement("DEC_CHANNEL_COUNT"), rowsReference, "updated"); }
+            
+            rowsReference = updateWithRetryBatch(psDeleteMessage);
+            
+            if (trace) { logBatchUpdate(getSQLStatement("DELETE_MESSAGE"), rowsReference, "deleted"); }
+                                    
+            psDeleteReference.close();
+            psDeleteReference = null;
+            psDeleteMessage.close();
+            psDeleteMessage = null;
+            psUpdateMessage.close();
+            psUpdateMessage = null;
+         }              
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+      	closeStatement(psDeleteReference);
+      	closeStatement(psDeleteMessage);
+      	closeStatement(psUpdateMessage);
+      	closeConnection(conn);         
+         try
+         {
+            wrap.end();
+         }
+         finally
+         {     
+            //And then release locks
+            this.releaseLocks(references);
+         }         
+      }      
+   }
+   
+   public void updateReferencesNotPagedInRange(long channelID, long orderStart, long orderEnd, long num) throws Exception
+   {
+      if (trace) { log.trace("Updating paaged references for channel " + channelID + " between " + orderStart + " and " + orderEnd); }
+      
+      Connection conn = null;
+      PreparedStatement ps = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+    
+      try
+      {
+         conn = ds.getConnection();
+         
+         ps = conn.prepareStatement(getSQLStatement("UPDATE_REFS_NOT_PAGED"));
+                 
+         ps.setLong(1, orderStart);
+         
+         ps.setLong(2, orderEnd);
+         
+         ps.setLong(3, channelID);
+         
+         int rows = updateWithRetry(ps);
+           
+         if (trace) { log.trace(JDBCUtil.statementToString(getSQLStatement("UPDATE_REFS_NOT_PAGED"), new Long(channelID),
+                                new Long(orderStart), new Long(orderEnd)) + " updated " + rows + " rows"); }
+
+         //Sanity check
+         if (rows != num)
+         {
+            throw new IllegalStateException("Did not update correct number of rows");
+         }            
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+      	closeStatement(ps);
+      	closeConnection(conn);       
+         wrap.end();
+      }
+   }
+   
+   public InitialLoadInfo mergeAndLoad(long fromChannelID, long toChannelID, int numberToLoad, long firstPagingOrder, long nextPagingOrder) throws Exception
+   {
+      if (trace) { log.trace("Merging channel from " + fromChannelID + " to " + toChannelID + " numberToLoad:" + numberToLoad + " firstPagingOrder:" + firstPagingOrder + " nextPagingOrder:" + nextPagingOrder); }
+      
+      Connection conn = null;
+      PreparedStatement ps = null;
+      ResultSet rs = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      PreparedStatement ps2 = null;
+    
+      try
+      {
+         conn = ds.getConnection();
+         
+         /*
+          * If channel is paging and has full size f
+          * 
+          * then we don't need to load any refs but we need to:
+          * 
+          * make sure the page ord is correct across the old paged and new refs
+          * 
+          * we know the max page ord (from the channel) for the old refs so we just need to:
+          * 
+          * 1) Iterate through the failed channel and update page_ord = max + 1, max + 2 etc
+          * 
+          * 2) update channel id
+          * 
+          * 
+          * If channel is not paging and the total refs before and after <=f
+          * 
+          * 1) Load all refs from failed channel
+          * 
+          * 2) Update channel id
+          * 
+          * return those refs
+          * 
+          * 
+          * If channel is not paging but total new refs > f
+          * 
+          * 1) Iterate through failed channel refs and take the first x to make the channel full
+          * 
+          * 2) Update the others with page_ord starting at zero 
+          * 
+          * 3) Update channel id
+          * 
+          * In general:
+          * 
+          * We have number to load n, max page size p
+          * 
+          * 1) Iterate through failed channel refs in page_ord order
+          * 
+          * 2) Put the first n in a List.
+          * 
+          * 3) Initialise page_ord_count to be p or 0 depending on whether it was specified
+          * 
+          * 4) Update the page_ord of the remaining refs accordiningly
+          * 
+          * 5) Update the channel id
+          * 
+          */
+         
+         //First load the refs from the failed channel
+
+         List refs = new ArrayList();
+         
+         ps = conn.prepareStatement(getSQLStatement("LOAD_REFS"));
+         
+         ps.setLong(1, fromChannelID);
+                 
+         rs = ps.executeQuery();
+         
+         int count = 0;
+         
+         boolean arePaged = false;
+         
+         long pageOrd = nextPagingOrder;
+         
+         while (rs.next())
+         {
+            long msgId = rs.getLong(1);            
+            int deliveryCount = rs.getInt(2);
+            long sched = rs.getLong(3);
+            
+            if (count < numberToLoad)
+            {           
+               ReferenceInfo ri = new ReferenceInfo(msgId, deliveryCount, sched);
+               
+               refs.add(ri);
+            }
+            
+            // Set page ord
+            
+            if (ps2 == null)
+            {
+               ps2 = conn.prepareStatement(getSQLStatement("UPDATE_PAGE_ORDER"));
+            }
+                
+            if (count < numberToLoad)
+            {
+               ps2.setNull(1, Types.BIGINT);
+               
+               if (trace) { log.trace("Set page ord to null"); }
+            }
+            else
+            {                                 
+               ps2.setLong(1, pageOrd);
+               
+               if (trace) { log.trace("Set page ord to " + pageOrd); }
+               
+               arePaged = true; 
+               
+               pageOrd++;                      
+            }
+            
+            ps2.setLong(2, msgId);
+            
+            ps2.setLong(3, fromChannelID);
+            
+            int rows = updateWithRetry(ps2);
+            
+            if (trace) { log.trace("Update page ord updated " + rows + " rows"); }
+
+            count++;            
+         }
+         
+         ps.close();
+         
+         // Now swap the channel id
+         
+         ps = conn.prepareStatement(getSQLStatement("UPDATE_CHANNEL_ID"));
+         
+         ps.setLong(1, toChannelID);
+         
+         ps.setLong(2, fromChannelID);
+         
+         int rows = updateWithRetry(ps);
+         
+         if (trace) { log.trace("Update channel id updated " + rows + " rows"); }
+                           
+         if (arePaged)
+         {            
+            return new InitialLoadInfo(new Long(firstPagingOrder), new Long(pageOrd - 1), refs);
+         }
+         else
+         {
+            return new InitialLoadInfo(null, null, refs);
+         }         
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+      	closeStatement(ps);
+      	closeStatement(ps2);
+      	closeConnection(conn);       
+         wrap.end();
+      }
+   }
+   
+   public void updatePageOrder(long channelID, List references) throws Exception
+   {
+      Connection conn = null;
+      PreparedStatement psUpdateReference = null;  
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      if (trace) { log.trace("Updating page order for channel:" + channelID); }
+        
+      try
+      {
+         conn = ds.getConnection();
+         
+         Iterator iter = references.iterator();
+         
+         if (usingBatchUpdates)
+         {
+            psUpdateReference = conn.prepareStatement(getSQLStatement("UPDATE_PAGE_ORDER"));
+         }
+         
+         while (iter.hasNext())
+         {
+            MessageReference ref = (MessageReference) iter.next();
+                 
+            if (!usingBatchUpdates)
+            {
+               psUpdateReference = conn.prepareStatement(getSQLStatement("UPDATE_PAGE_ORDER"));
+            }
+            
+            psUpdateReference.setLong(1, ref.getPagingOrder());
+
+            psUpdateReference.setLong(2, ref.getMessage().getMessageID());
+            
+            psUpdateReference.setLong(3, channelID);
+            
+            if (usingBatchUpdates)
+            {
+               psUpdateReference.addBatch();
+            }
+            else
+            {
+               int rows = updateWithRetry(psUpdateReference);
+               
+               if (trace) { log.trace("Updated " + rows + " rows"); }
+               
+               psUpdateReference.close();
+               psUpdateReference = null;
+            }
+         }
+                     
+         if (usingBatchUpdates)
+         {
+            int[] rowsReference = updateWithRetryBatch(psUpdateReference);
+            
+            if (trace) { logBatchUpdate(getSQLStatement("UPDATE_PAGE_ORDER"), rowsReference, "updated"); }
+                        
+            psUpdateReference.close();
+            psUpdateReference = null;
+         }
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+      	closeStatement(psUpdateReference);
+      	closeConnection(conn);       
+         wrap.end();
+      }    
+   }
+      
+   public List getPagedReferenceInfos(long channelID, long orderStart, int number) throws Exception
+   {
+      if (trace) { log.trace("loading message reference info for channel " + channelID + " from " + orderStart + " number " + number);      }
+                 
+      List refs = new ArrayList();
+      
+      Connection conn = null;
+      PreparedStatement ps = null;
+      ResultSet rs = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      try
+      {
+         conn = ds.getConnection();
+         
+         ps = conn.prepareStatement(getSQLStatement("LOAD_PAGED_REFS"));
+         
+         ps.setLong(1, channelID);
+         
+         ps.setLong(2, orderStart);
+         
+         ps.setLong(3, orderStart + number - 1);
+         
+         rs = ps.executeQuery();
+         
+         long ord = orderStart;
+         
+         while (rs.next())
+         {
+            long msgId = rs.getLong(1);     
+            int deliveryCount = rs.getInt(2);
+            int pageOrd = rs.getInt(3);
+            long sched = rs.getLong(4);
+            
+            //Sanity check
+            if (pageOrd != ord)
+            {
+               throw new IllegalStateException("Unexpected pageOrd: " + pageOrd + " expected: " + ord);
+            }
+            
+            ReferenceInfo ri = new ReferenceInfo(msgId, deliveryCount, sched);
+            
+            refs.add(ri);
+            ord++;
+         }
+         
+         //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)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+      	closeResultSet(rs);
+      	closeStatement(ps);
+      	closeConnection(conn);       
+         wrap.end();
+      }      
+   }   
+   
+   /*
+    * Load the initial, non paged refs
+    */
+   public InitialLoadInfo loadFromStart(long channelID, int number) throws Exception
+   {
+      if (trace) { log.trace("loading initial reference infos for channel " + channelID);  }
+                    
+      Connection conn = null;
+      PreparedStatement ps = null;
+      ResultSet rs = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+                                
+      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 = new Long(rs.getLong(1));
+         
+         if (rs.wasNull())
+         {
+            minOrdering = null;
+         }
+         
+         Long maxOrdering = new Long(rs.getLong(2));
+         
+         if (rs.wasNull())
+         {
+            maxOrdering = null;
+         }
+         
+         ps.close();
+         
+         conn.close();
+         
+         conn = ds.getConnection();         
+         
+         ps = conn.prepareStatement(getSQLStatement("LOAD_UNPAGED_REFS"));
+         
+         ps.setLong(1, channelID);
+                 
+         rs = ps.executeQuery();
+         
+         List refs = new ArrayList();
+         
+         int count = 0;
+         while (rs.next())
+         {
+            long msgId = rs.getLong(1);            
+            int deliveryCount = rs.getInt(2);
+            long sched = rs.getLong(3);
+            
+            ReferenceInfo ri = new ReferenceInfo(msgId, deliveryCount, sched);
+            
+            if (count < number)
+            {
+               refs.add(ri);
+            }            
+            
+            count++;
+         }
+                  
+         //No refs paged
+            
+         if (count > number)
+         {
+            throw new IllegalStateException("Cannot load channel " + channelID + " since the fullSize parameter is too small to load " +
+                     " all the required references, fullSize needs to be at least " + count + " it is currently " + number);
+         }
+                         
+         return new InitialLoadInfo(minOrdering, maxOrdering, refs);
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+      	closeResultSet(rs);
+      	closeStatement(ps);      	
+      	closeConnection(conn);       
+         wrap.end();
+      }      
+   }   
+   
+   
+   // End of paging functionality
+   // ===========================
+   
+   public void addReference(long channelID, MessageReference ref, Transaction tx) throws Exception
+   {      
+      if (tx != null)
+      {
+         //In a tx so we just add the ref in the tx in memory for now
+
+         TransactionCallback callback = getCallback(tx);
+
+         callback.addReferenceToAdd(channelID, ref);
+      }
+      else
+      {         
+         //No tx so add the ref directly in the db
+         
+         TransactionWrapper wrap = new TransactionWrapper();
+         
+         PreparedStatement psReference = null;
+         PreparedStatement psMessage = null;
+         
+         Connection conn = ds.getConnection();
+         
+         Message m = ref.getMessage();     
+           
+         try
+         {            
+            // Get lock on message
+            LockMap.instance.obtainLock(m);
+                                    
+            psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
+            
+            // Add the reference
+            addReference(channelID, ref, psReference, false);
+            
+            int rows = updateWithRetry(psReference);      
+            
+            if (trace) { log.trace("Inserted " + rows + " rows"); }
+              
+            if (!m.isPersisted())
+            {
+               // First time so persist the message
+               psMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+               
+               storeMessage(m, psMessage);
+               
+               m.setPersisted(true);
+            }
+            else
+            {
+               //Update the message's channel count
+               psMessage = conn.prepareStatement(getSQLStatement("INC_CHANNEL_COUNT"));
+               
+               incrementChannelCount(m, psMessage);
+            }
+                           
+            rows = updateWithRetry(psMessage);
+            
+            if (trace) { log.trace("Inserted/updated " + rows + " rows"); }     
+            
+            log.trace("message Inserted/updated " + rows + " rows");            
+         }
+         catch (Exception e)
+         {
+            wrap.exceptionOccurred();
+            throw e;
+         }
+         finally
+         {
+         	closeStatement(psReference);
+         	closeStatement(psMessage);
+         	closeConnection(conn);  
+            try
+            {
+               wrap.end();
+            }
+            finally
+            {   
+               //Release Lock
+               LockMap.instance.releaseLock(m);
+            }
+         }      
+      }
+   }
+   
+   public void updateDeliveryCount(long channelID, MessageReference ref) throws Exception
+   {
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      PreparedStatement psReference = null;
+      
+      Connection conn = ds.getConnection();
+       
+      try
+      {                                    
+         psReference = conn.prepareStatement(getSQLStatement("UPDATE_DELIVERY_COUNT"));
+         
+         psReference.setInt(1, ref.getDeliveryCount());
+         
+         psReference.setLong(2, channelID);
+         
+         psReference.setLong(3, ref.getMessage().getMessageID());
+         
+         int rows = updateWithRetry(psReference);
+
+         if (trace) { log.trace("Updated " + rows + " rows"); }
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+      	closeStatement(psReference);
+      	closeConnection(conn);
+         wrap.end();                        
+      }  
+   }
+   
+   public void removeReference(long channelID, MessageReference ref, Transaction tx) throws Exception
+   {      
+      if (tx != null)
+      {
+         //In a tx so we just add the ref in the tx in memory for now
+
+         TransactionCallback callback = getCallback(tx);
+
+         callback.addReferenceToRemove(channelID, ref);
+      }
+      else
+      {         
+         //No tx so we remove the reference directly from the db
+         
+         TransactionWrapper wrap = new TransactionWrapper();
+         
+         PreparedStatement psReference = null;
+         PreparedStatement psUpdate = null;
+         PreparedStatement psMessage = null;
+         
+         Connection conn = ds.getConnection();
+         
+         Message m = ref.getMessage();         
+         
+         try
+         {
+            //get lock on message
+            LockMap.instance.obtainLock(m);
+                              
+            psReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
+            
+            //Remove the message reference
+            removeReference(channelID, ref, psReference);
+            
+            int rows = updateWithRetry(psReference);
+            
+            if (rows != 1)
+            {
+               log.warn("Failed to remove row for: " + ref);
+               return;
+            }
+            
+            if (trace) { log.trace("Deleted " + rows + " rows"); }
+            
+            //Update the messages channel count
+            
+            psUpdate = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
+            
+            decrementChannelCount(m, psUpdate);
+            
+            rows = updateWithRetry(psUpdate);
+            
+            if (trace) { log.trace("Updated " + rows + " rows"); } 
+            
+            //Delete the message (if necessary)
+            
+            psMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+            
+            removeMessage(m, psMessage);
+                       
+            rows = updateWithRetry(psMessage);
+            
+            if (trace) { log.trace("Delete " + rows + " rows"); }                           
+         }
+         catch (Exception e)
+         {
+            wrap.exceptionOccurred();
+            throw e;
+         }
+         finally
+         {
+         	closeStatement(psReference);
+         	closeStatement(psUpdate);
+         	closeStatement(psMessage);
+         	closeConnection(conn);
+            try
+            {
+               wrap.end();               
+            }
+            finally
+            {      
+               //release the lock
+               LockMap.instance.releaseLock(m);
+            }
+         }      
+      }
+   }
+   
+   public boolean referenceExists(long messageID) throws Exception
+   {
+      Connection conn = null;
+      PreparedStatement st = null;
+      ResultSet rs = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+
+      try
+      {
+         conn = ds.getConnection();
+
+         st = conn.prepareStatement(getSQLStatement("SELECT_EXISTS_REF_MESSAGE_ID"));
+         st.setLong(1, messageID);
+
+         rs = st.executeQuery();
+
+         if (rs.next())
+         {
+            return true;
+         }
+         else
+         {
+            return false;
+         }
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+      	closeResultSet(rs);
+      	closeStatement(st);
+      	closeConnection(conn);
+         wrap.end();
+      }
+   }
+
+   // Public --------------------------------------------------------
+   
+   public String toString()
+   {
+      return "JDBCPersistenceManager[" + Integer.toHexString(hashCode()) + "]";
+   }   
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+      
+   protected TransactionCallback getCallback(Transaction tx)
+   {
+      TransactionCallback callback = (TransactionCallback) tx.getCallback(this);
+
+      if (callback == null)
+      {
+         callback = new TransactionCallback(tx);
+
+         tx.addCallback(callback, this);
+      }
+
+      return callback;
+   }
+   
+   /**
+    * We order the list of references in ascending message order thus preventing deadlock when 2 or
+    * more channels are updating the same messages in different transactions.
+    */
+   protected void orderReferences(List references)
+   {      
+      Collections.sort(references, MessageOrderComparator.instance);
+   }
+   
+   protected void handleBeforeCommit1PC(List refsToAdd, List refsToRemove, Transaction tx)
+      throws Exception
+   {
+      //TODO - A slight optimisation - it's possible we have refs referring to the same message
+      //       so we will end up acquiring the lock more than once which is unnecessary. If find
+      //       unique set of messages can avoid this.
+
+      List allRefs = new ArrayList(refsToAdd.size() + refsToRemove.size());
+
+      for(Iterator i = refsToAdd.iterator(); i.hasNext(); )
+      {
+         ChannelRefPair pair = (ChannelRefPair)i.next();
+         allRefs.add(pair.ref);
+      }
+
+      for(Iterator i = refsToRemove.iterator(); i.hasNext(); )
+      {
+         ChannelRefPair pair = (ChannelRefPair)i.next();
+         allRefs.add(pair.ref);
+      }
+            
+      orderReferences(allRefs);
+      
+      // For one phase we simply add rows corresponding to the refs and remove rows corresponding to
+      // the deliveries in one jdbc tx. We also need to store or remove messages as necessary,
+      // depending on whether they've already been stored or still referenced by other channels.
+         
+      Connection conn = null;
+      PreparedStatement psReference = null;
+      PreparedStatement psInsertMessage = null;
+      PreparedStatement psIncMessage = null;
+      PreparedStatement psDecMessage = null;
+      PreparedStatement psDeleteMessage = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      try
+      {
+         conn = ds.getConnection();
+         
+         // Obtain locks on all messages
+         getLocks(allRefs);
+         
+         // First the adds
+
+         boolean messageInsertsInBatch = false;
+         boolean messageUpdatesInBatch = false;
+         boolean batch = usingBatchUpdates && refsToAdd.size() > 0;
+
+         if (batch)
+         {
+            psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
+            psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+            psIncMessage = conn.prepareStatement(getSQLStatement("INC_CHANNEL_COUNT"));
+         }
+
+         for(Iterator i = refsToAdd.iterator(); i.hasNext(); )
+         {
+            ChannelRefPair pair = (ChannelRefPair)i.next();
+            MessageReference ref = pair.ref;
+                                                
+            if (!batch)
+            {
+               psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
+            }
+            
+            // Now store the reference
+            addReference(pair.channelID, ref, psReference, false);
+              
+            if (batch)
+            {
+               psReference.addBatch();
+            }
+            else
+            {
+               int rows = updateWithRetry(psReference);
+               
+               if (trace) { log.trace("Inserted " + rows + " rows"); }                              
+               
+               psReference.close();
+               psReference = null;
+            }
+            
+            Message m = ref.getMessage();        
+            
+            if (!batch)
+            {
+               psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+               psIncMessage = conn.prepareStatement(getSQLStatement("INC_CHANNEL_COUNT"));
+            }
+                         
+            boolean added;
+            if (!m.isPersisted())
+            {               
+               // First time so add message
+               storeMessage(m, psInsertMessage);
+               added = true;
+               m.setPersisted(true);
+            }
+            else
+            {               
+               // Update message channel count
+               incrementChannelCount(m, psIncMessage);
+               added = false;
+            }
+            
+            if (batch)
+            {
+               if (added)
+               {
+                  psInsertMessage.addBatch();
+                  if (trace) { log.trace("Message does not already exist so inserting it"); }
+                  messageInsertsInBatch = true;
+               }
+               else
+               { 
+                  if (trace) { log.trace("Message already exists so updating count"); }
+                  psIncMessage.addBatch();
+                  messageUpdatesInBatch = true;
+               }
+            }
+            else
+            {
+               if (added)
+               {
+                  if (trace) { log.trace("Message does not already exist so inserting it"); }
+                  int rows = updateWithRetry(psInsertMessage);
+                  if (trace) { log.trace("Inserted " + rows + " rows"); }
+               }
+               else
+               {
+                  if (trace) { log.trace("Message already exists so updating count"); }
+                  int rows = updateWithRetry(psIncMessage);
+                  if (trace) { log.trace("Updated " + rows + " rows"); }
+               }
+               psInsertMessage.close();
+               psInsertMessage = null;
+               psIncMessage.close();
+               psIncMessage = null;
+            }
+         }         
+         
+         if (batch)
+         {
+            // Process the add batch
+
+            int[] rowsReference = updateWithRetryBatch(psReference);
+            
+            if (trace) { logBatchUpdate(getSQLStatement("INSERT_MESSAGE_REF"), rowsReference, "inserted"); }
+            
+            if (messageInsertsInBatch)
+            {
+               int[] rowsMessage = updateWithRetryBatch(psInsertMessage);
+               if (trace) { logBatchUpdate(getSQLStatement("INSERT_MESSAGE"), rowsMessage, "inserted"); }
+            }
+
+            if (messageUpdatesInBatch)
+            {
+               int[] rowsMessage = updateWithRetryBatch(psIncMessage);
+               if (trace) { logBatchUpdate(getSQLStatement("INC_CHANNEL_COUNT"), rowsMessage, "updated"); }
+            }
+            
+            psReference.close();
+            psReference = null;
+            psInsertMessage.close();
+            psInsertMessage = null;
+            psIncMessage.close();
+            psIncMessage = null;
+         }
+         
+         // Now the removes
+
+         psReference = null;
+         psDeleteMessage = null;
+         batch = usingBatchUpdates && refsToRemove.size() > 0;
+
+         if (batch)
+         {
+            psReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
+            psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+            psDecMessage = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
+         }
+
+         
+         for(Iterator i = refsToRemove.iterator(); i.hasNext(); )
+         {
+            ChannelRefPair pair = (ChannelRefPair)i.next();
+            
+            if (!batch)
+            {
+               psReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
+            }
+            
+            removeReference(pair.channelID, pair.ref, psReference);
+            
+            if (batch)
+            {
+               psReference.addBatch();
+            }
+            else
+            {
+               int rows = updateWithRetry(psReference);
+               if (trace) { log.trace("Deleted " + rows + " rows"); }
+               psReference.close();
+               psReference = null;
+            }
+            
+            if (!batch)
+            {
+               psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+               psDecMessage = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
+            }
+            
+            Message m = pair.ref.getMessage();
+                                
+            // Update the channel count
+            
+            decrementChannelCount(m, psDecMessage);
+            
+            // Delete the message (if necessary)
+            
+            removeMessage(m, psDeleteMessage);
+                       
+            if (batch)
+            {
+               psDecMessage.addBatch();
+               psDeleteMessage.addBatch();
+            }
+            else
+            {
+               int rows = updateWithRetry(psDecMessage);
+               if (trace) { log.trace("Updated " + rows + " rows"); }
+               
+               rows = updateWithRetry(psDeleteMessage);
+               if (trace) { log.trace("Deleted " + rows + " rows"); }
+
+               psDeleteMessage.close();
+               psDeleteMessage = null;
+               psDecMessage.close();
+               psDecMessage = null;
+            }            
+         }
+         
+         if (batch)
+         {
+            // Process the remove batch
+
+            int[] rows = updateWithRetryBatch(psReference);
+            
+            if (trace) { logBatchUpdate(getSQLStatement("DELETE_MESSAGE_REF"), rows, "deleted"); }
+            
+            rows = updateWithRetryBatch(psDecMessage);
+            
+            if (trace) { logBatchUpdate(getSQLStatement("DEC_CHANNEL_COUNT"), rows, "updated"); }
+
+            rows = updateWithRetryBatch(psDeleteMessage);
+            
+            if (trace) { logBatchUpdate(getSQLStatement("DELETE_MESSAGE"), rows, "deleted"); }
+
+            psReference.close();
+            psReference = null;
+            psDeleteMessage.close();
+            psDeleteMessage = null;
+            psDecMessage.close();
+            psDecMessage = null;
+         }         
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();                  
+         throw e;
+      }
+      finally
+      {
+      	closeStatement(psReference);
+      	closeStatement(psInsertMessage);
+      	closeStatement(psIncMessage);
+      	closeStatement(psDecMessage);
+      	closeStatement(psDeleteMessage);
+      	closeConnection(conn);        
+         try
+         {
+            wrap.end();                        
+         }
+         finally
+         {  
+            //Release the locks
+            this.releaseLocks(allRefs);
+         }
+      }
+   }
+   
+   protected void handleBeforeCommit2PC(List refsToRemove, Transaction tx)
+      throws Exception
+   {          
+      Connection conn = null;
+      PreparedStatement psUpdateMessage = null;
+      PreparedStatement psDeleteMessage = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      List refs = new ArrayList(refsToRemove.size());
+      Iterator iter = refsToRemove.iterator();
+      while (iter.hasNext())
+      {
+         ChannelRefPair pair = (ChannelRefPair)iter.next();
+         refs.add(pair.ref);
+      }
+            
+      orderReferences(refs);      
+      
+      try
+      {
+         //get locks on all the refs
+         this.getLocks(refs);
+         
+         conn = ds.getConnection();
+                  
+         //2PC commit
+         
+         //First we commit any refs in state "+" to "C" and delete any
+         //refs in state "-", then we
+         //remove any messages due to refs we just removed
+         //if they're not referenced elsewhere
+         
+         commitPreparedTransaction(tx, conn);
+         
+         boolean batch = usingBatchUpdates && refsToRemove.size() > 0;
+
+         if (batch)
+         {
+            psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+            psUpdateMessage = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
+         }
+                  
+         iter = refsToRemove.iterator();
+         while (iter.hasNext())
+         {
+            ChannelRefPair pair = (ChannelRefPair) iter.next();
+            
+            MessageReference ref = pair.ref;
+            
+            if (!batch)
+            {
+               psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+               psUpdateMessage = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
+            }
+            
+            Message m = ref.getMessage();
+                                   
+            //We may need to remove the message itself
+            
+            //Update the channel count
+            
+            decrementChannelCount(m, psUpdateMessage);
+            
+            //Remove the message (if necessary)
+            
+            removeMessage(m, psDeleteMessage);          
+                           
+            if (batch)
+            {
+               psUpdateMessage.addBatch();
+                
+               psDeleteMessage.addBatch(); 
+            }
+            else
+            {
+               int rows = updateWithRetry(psUpdateMessage);
+               
+               if (trace) { log.trace("Updated " + rows + " rows"); }
+               
+               rows = updateWithRetry(psDeleteMessage);
+               
+               if (trace) { log.trace("Deleted " + rows + " rows"); }
+               
+               psDeleteMessage.close();
+               psDeleteMessage = null;
+               psUpdateMessage.close();
+               psUpdateMessage = null;
+            }
+         }         
+         
+         if (batch)
+         {
+            int[] rows = updateWithRetryBatch(psUpdateMessage);
+            
+            if (trace) { logBatchUpdate(getSQLStatement("DEC_CHANNEL_COUNT"), rows, "updated"); }
+            
+            psUpdateMessage.close();
+            psUpdateMessage = null;
+            
+            rows = updateWithRetryBatch(psDeleteMessage);
+            
+            if (trace) { logBatchUpdate(getSQLStatement("DELETE_MESSAGE"), rows, "deleted"); }
+            
+            psDeleteMessage.close();
+            psDeleteMessage = null;                           
+         }         
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+      	closeStatement(psDeleteMessage);
+      	closeStatement(psUpdateMessage);
+      	closeConnection(conn);        
+         try
+         {
+            wrap.end();
+         }
+         finally
+         {
+            //release the locks
+            this.releaseLocks(refs);
+         }
+      }
+   }
+   
+   protected void handleBeforePrepare(List refsToAdd, List refsToRemove, Transaction tx) throws Exception
+   {
+      //We only need to lock on the adds
+      List refs = new ArrayList(refsToAdd.size());
+      
+      Iterator iter = refsToAdd.iterator();
+      while (iter.hasNext())
+      {
+         ChannelRefPair pair = (ChannelRefPair)iter.next();
+         
+         refs.add(pair.ref);
+      }
+      
+      orderReferences(refs);
+      
+      //We insert a tx record and
+      //a row for each ref with +
+      //and update the row for each delivery with "-"
+      
+      PreparedStatement psReference = null;
+      PreparedStatement psInsertMessage = null;
+      PreparedStatement psUpdateMessage = null;
+      Connection conn = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      try
+      {
+         //get the locks
+         getLocks(refs);
+         
+         conn = ds.getConnection();
+         
+         //Insert the tx record
+         if (!refsToAdd.isEmpty() || !refsToRemove.isEmpty())
+         {
+            addTXRecord(conn, tx);
+         }
+         
+         iter = refsToAdd.iterator();
+         
+         boolean batch = usingBatchUpdates && refsToAdd.size() > 1;
+         boolean messageInsertsInBatch = false;
+         boolean messageUpdatesInBatch = false;
+         if (batch)
+         {
+            psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
+            psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+            psUpdateMessage = conn.prepareStatement(getSQLStatement("INC_CHANNEL_COUNT"));
+         }
+         
+         while (iter.hasNext())
+         {
+            ChannelRefPair pair = (ChannelRefPair) iter.next();
+            
+            if (!batch)
+            {
+               psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
+            }
+            
+            prepareToAddReference(pair.channelID, pair.ref, tx, psReference);
+            
+            if (batch)
+            {
+               psReference.addBatch();
+            }
+            else
+            {
+               int rows = updateWithRetry(psReference);
+               
+               if (trace) { log.trace("Inserted " + rows + " rows"); }
+               
+               psReference.close();
+               psReference = null;
+            }
+            
+            if (!batch)
+            {
+               psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+               psUpdateMessage = conn.prepareStatement(getSQLStatement("INC_CHANNEL_COUNT"));
+            }
+            
+            Message m = pair.ref.getMessage();
+                   
+            boolean added;         
+            
+            if (!m.isPersisted())
+            {
+               //First time so persist the message
+               storeMessage(m, psInsertMessage);
+               
+               m.setPersisted(true);
+               
+               added = true;
+            }
+            else
+            {
+               //Update message channel count
+               incrementChannelCount(m, psUpdateMessage);
+               
+               added = false;
+            }
+            
+            if (batch)
+            {
+               if (added)
+               {
+                  psInsertMessage.addBatch();
+                  messageInsertsInBatch = true;
+               }
+               else
+               {
+                  psUpdateMessage.addBatch();
+                  messageUpdatesInBatch = true;
+               }
+            }
+            else
+            {
+               if (added)
+               {
+                  int rows = updateWithRetry(psInsertMessage);
+                  
+                  if (trace) { log.trace("Inserted " + rows + " rows"); }
+               }
+               else
+               {
+                  int rows = updateWithRetry(psUpdateMessage);
+                  
+                  if (trace) { log.trace("Updated " + rows + " rows"); }
+               }
+               psInsertMessage.close();
+               psInsertMessage = null;
+               psUpdateMessage.close();
+               psUpdateMessage = null;
+            }
+         }         
+         
+         if (batch)
+         {
+            int[] rowsReference = updateWithRetryBatch(psReference);
+            
+            if (trace) { logBatchUpdate(getSQLStatement("INSERT_MESSAGE_REF"), rowsReference, "inserted"); }
+            
+            if (messageInsertsInBatch)
+            {
+               int[] rowsMessage = updateWithRetryBatch(psInsertMessage);
+               
+               if (trace) { logBatchUpdate(getSQLStatement("INSERT_MESSAGE"), rowsMessage, "inserted"); }
+            }
+            if (messageUpdatesInBatch)
+            {
+               int[] rowsMessage = updateWithRetryBatch(psUpdateMessage);
+               
+               if (trace) { logBatchUpdate(getSQLStatement("INC_CHANNEL_COUNT"), rowsMessage, "updated"); }
+            }
+            
+            psReference.close();
+            psReference = null;
+            psInsertMessage.close();
+            psInsertMessage = null;
+            psUpdateMessage.close();
+            psUpdateMessage = null;
+         }
+         
+         //Now the removes
+         
+         iter = refsToRemove.iterator();
+         
+         batch = usingBatchUpdates && refsToRemove.size() > 1;
+         if (batch)
+         {
+            psReference = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_REF"));
+         }
+
+         while (iter.hasNext())
+         {
+            ChannelRefPair pair = (ChannelRefPair) iter.next();
+            
+            if (!batch)
+            {
+               psReference = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_REF"));
+            }
+            
+            prepareToRemoveReference(pair.channelID, pair.ref, tx, psReference);
+            
+            if (batch)
+            {
+               psReference.addBatch();
+            }
+            else
+            {
+               int rows = updateWithRetry(psReference);
+               
+               if (trace) { log.trace("updated " + rows + " rows"); }
+               
+               psReference.close();
+               psReference = null;
+            }
+         }
+         
+         if (batch)
+         {
+            int[] rows = updateWithRetryBatch(psReference);
+            
+            if (trace) { logBatchUpdate(getSQLStatement("UPDATE_MESSAGE_REF"), rows, "updated"); }
+            
+            psReference.close();
+            psReference = null;
+         }
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+      	closeStatement(psReference);
+      	closeStatement(psInsertMessage);
+      	closeStatement(psUpdateMessage);
+      	closeConnection(conn);         
+         try
+         {
+            wrap.end();            
+         }
+         finally
+         {
+            //release the locks
+            
+            this.releaseLocks(refs);
+         }
+      }
+   }
+   
+   protected void handleBeforeRollback(List refsToAdd, Transaction tx) throws Exception
+   {
+      //remove refs marked with +
+      //and update rows marked with - to C
+            
+      PreparedStatement psDeleteMessage = null;
+      PreparedStatement psUpdateMessage = null;
+      Connection conn = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      List refs = new ArrayList(refsToAdd.size());
+      
+      Iterator iter = refsToAdd.iterator();
+      
+      while (iter.hasNext())
+      {
+         ChannelRefPair pair = (ChannelRefPair)iter.next();
+         refs.add(pair.ref);
+      }
+      
+      orderReferences(refs);
+      
+      try
+      {
+         this.getLocks(refs);
+         
+         conn = ds.getConnection();
+         
+         rollbackPreparedTransaction(tx, conn);
+         
+         iter = refsToAdd.iterator();
+         
+         boolean batch = usingBatchUpdates && refsToAdd.size() > 1;
+
+         if (batch)
+         {
+            psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+            psUpdateMessage = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
+         }
+                                 
+         while (iter.hasNext())
+         {
+            ChannelRefPair pair = (ChannelRefPair) iter.next();
+            
+            if (!batch)
+            {
+               psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+               psUpdateMessage = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
+            }
+            
+            Message m = pair.ref.getMessage();
+                                         
+            //We may need to remove the message for messages added during the prepare stage
+                        
+            //update the channel count
+            
+            decrementChannelCount(m, psUpdateMessage);
+            
+            //remove the message (if necessary)
+            
+            removeMessage(m, psDeleteMessage);
+                                        
+            if (batch)
+            {
+               psUpdateMessage.addBatch();
+               
+               psDeleteMessage.addBatch();
+            }
+            else
+            {
+               int rows = updateWithRetry(psUpdateMessage);
+               
+               if (trace) { log.trace("updated " + rows + " rows"); }
+               
+               rows = updateWithRetry(psDeleteMessage);
+               
+               if (trace) { log.trace("deleted " + rows + " rows"); }
+               
+               psDeleteMessage.close();
+               psDeleteMessage = null;
+               psUpdateMessage.close();
+               psUpdateMessage = null;
+            }            
+         }
+         
+         if (batch)
+         {
+            int[] rows = updateWithRetryBatch(psUpdateMessage);
+            
+            if (trace) { logBatchUpdate(getSQLStatement("DEC_CHANNEL_COUNT"), rows, "updated"); }
+            
+            rows = updateWithRetryBatch(psDeleteMessage);
+            
+            if (trace) { logBatchUpdate(getSQLStatement("DELETE_MESSAGE"), rows, "deleted"); }
+            
+            psDeleteMessage.close();
+            psDeleteMessage = null;
+            
+            psUpdateMessage.close();
+            psUpdateMessage = null;            
+         }
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+      	closeStatement(psDeleteMessage);
+      	closeStatement(psUpdateMessage);      	
+      	closeConnection(conn);                
+         try
+         {
+            wrap.end();
+         }
+         finally
+         {
+            //release locks
+            this.releaseLocks(refs);
+         }
+      }      
+   }
+   
+   
+   protected void addTXRecord(Connection conn, Transaction tx) throws Exception
+   {
+      if (trace)
+      {
+         log.trace("Inserting tx record for " + tx);
+      }
+      
+      PreparedStatement ps = null;
+      String statement = "UNDEFINED";
+      int rows = -1;
+      int formatID = -1;
+      try
+      {
+         statement = getSQLStatement("INSERT_TRANSACTION");
+         
+         ps = conn.prepareStatement(statement);
+         
+         ps.setLong(1, tx.getId());
+         
+         Xid xid = tx.getXid();
+         
+         formatID = xid.getFormatId();
+         
+         setVarBinaryColumn(2, ps, xid.getBranchQualifier());
+         
+         ps.setInt(3, formatID);
+         
+         setVarBinaryColumn(4, ps, xid.getGlobalTransactionId());
+         
+         rows = updateWithRetry(ps);
+         
+      }
+      finally
+      {
+         if (trace)
+         {
+            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)"));
+         }
+         closeStatement(ps);      
+      }
+   }
+   
+   protected void removeTXRecord(Connection conn, Transaction tx) throws Exception
+   {
+      PreparedStatement ps = null;
+      try
+      {
+         ps = conn.prepareStatement(getSQLStatement("DELETE_TRANSACTION"));
+         
+         ps.setLong(1, tx.getId());
+         
+         int rows = updateWithRetry(ps);
+         
+         if (trace)
+         {
+            log.trace(JDBCUtil.statementToString(getSQLStatement("DELETE_TRANSACTION"), new Long(tx.getId())) + " removed " + rows + " row(s)");
+         }
+      }
+      finally
+      {
+      	closeStatement(ps);    
+      }
+   }  
+   
+   protected void addReference(long channelID, MessageReference ref,
+                               PreparedStatement ps, boolean paged) throws Exception
+   {
+      if (trace) { log.trace("adding " + ref + " to channel " + channelID); }
+      
+      ps.setLong(1, channelID);
+      ps.setLong(2, ref.getMessage().getMessageID());
+      ps.setNull(3, Types.BIGINT);
+      ps.setString(4, "C");
+      ps.setLong(5, getOrdering());
+      if (paged)
+      {
+         ps.setLong(6, ref.getPagingOrder());
+      }
+      else
+      {
+         ps.setNull(6, Types.BIGINT);
+      }
+      ps.setInt(7, ref.getDeliveryCount());
+      ps.setLong(8, ref.getScheduledDeliveryTime());
+   }
+   
+   protected void removeReference(long channelID, MessageReference ref, PreparedStatement ps)
+      throws Exception
+   {
+      if (trace) { log.trace("removing " + ref + " from channel " + channelID); }
+      
+      ps.setLong(1, ref.getMessage().getMessageID());
+      ps.setLong(2, channelID);      
+   }
+   
+   protected void prepareToAddReference(long channelID, MessageReference ref, Transaction tx, PreparedStatement ps)
+     throws Exception
+   {
+      if (trace) { log.trace("adding " + ref + " to channel " + channelID + (tx == null ? " non-transactionally" : " on transaction: " + tx)); }
+      
+      ps.setLong(1, channelID);
+      ps.setLong(2, ref.getMessage().getMessageID());
+      ps.setLong(3, tx.getId());
+      ps.setString(4, "+");
+      ps.setLong(5, getOrdering());
+      ps.setNull(6, Types.BIGINT);      
+      ps.setInt(7, ref.getDeliveryCount());
+      ps.setLong(8, ref.getScheduledDeliveryTime());
+   }
+   
+   protected void prepareToRemoveReference(long channelID, MessageReference ref, Transaction tx, PreparedStatement ps)
+      throws Exception
+   {
+      if (trace)
+      {
+         log.trace("removing " + ref + " from channel " + channelID
+               + (tx == null ? " non-transactionally" : " on transaction: " + tx));
+      }
+      
+      ps.setLong(1, tx.getId()); 
+      ps.setLong(2, ref.getMessage().getMessageID());
+      ps.setLong(3, channelID);           
+   }
+   
+   protected void commitPreparedTransaction(Transaction tx, Connection conn) throws Exception
+   {
+      PreparedStatement ps = null;
+      
+      if (trace) { log.trace(this + " commitPreparedTransaction, tx= " + tx); }
+        
+      try
+      {
+         ps = conn.prepareStatement(getSQLStatement("COMMIT_MESSAGE_REF1"));
+         
+         ps.setLong(1, tx.getId());        
+         
+         int rows = updateWithRetry(ps);
+         
+         if (trace)
+         {
+            log.trace(JDBCUtil.statementToString(getSQLStatement("COMMIT_MESSAGE_REF1"), new Long(tx.getId())) + " removed " + rows + " row(s)");
+         }
+         
+         ps.close();
+         ps = conn.prepareStatement(getSQLStatement("COMMIT_MESSAGE_REF2"));
+         ps.setLong(1, tx.getId());         
+         
+         rows = updateWithRetry(ps);
+         
+         if (trace)
+         {
+            log.trace(JDBCUtil.statementToString(getSQLStatement("COMMIT_MESSAGE_REF2"), new Long(tx.getId())) + " updated " + rows
+                  + " row(s)");
+         }
+         
+         removeTXRecord(conn, tx);
+      }
+      finally
+      {
+      	closeStatement(ps);
+      }
+   }
+   
+   protected void rollbackPreparedTransaction(Transaction tx, Connection conn) throws Exception
+   {
+      PreparedStatement ps = null;
+      
+      try
+      {
+         ps = conn.prepareStatement(getSQLStatement("ROLLBACK_MESSAGE_REF1"));
+         
+         ps.setLong(1, tx.getId());         
+         
+         int rows = updateWithRetry(ps);
+         
+         if (trace)
+         {
+            log.trace(JDBCUtil.statementToString(getSQLStatement("ROLLBACK_MESSAGE_REF1"), new Long(tx.getId())) + " removed " + rows + " row(s)");
+         }
+         
+         ps.close();
+         
+         ps = conn.prepareStatement(getSQLStatement("ROLLBACK_MESSAGE_REF2"));
+         ps.setLong(1, tx.getId());
+         
+         rows = updateWithRetry(ps);
+         
+         if (trace)
+         {
+            log.trace(JDBCUtil.statementToString(getSQLStatement("ROLLBACK_MESSAGE_REF2"), new Long(tx.getId())) + " updated " + rows
+                  + " row(s)");
+         }
+         
+         removeTXRecord(conn, tx);
+      }
+      finally
+      {
+      	closeStatement(ps);
+      }
+   }
+   
+   protected byte[] mapToBytes(Map map) throws Exception
+   {
+      if (map == null || map.isEmpty())
+      {
+         return null;
+      }
+      
+      final int BUFFER_SIZE = 1024;
+       
+      ByteArrayOutputStream bos = new ByteArrayOutputStream(BUFFER_SIZE);
+      
+      DataOutputStream oos = new DataOutputStream(bos);
+      
+      StreamUtils.writeMap(oos, map, true);
+      
+      oos.close();
+      
+      return bos.toByteArray();
+   }
+   
+   protected HashMap bytesToMap(byte[] bytes) throws Exception
+   {
+      if (bytes == null)
+      {
+         return new HashMap();
+      }
+       
+      ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
+      
+      DataInputStream dais = new DataInputStream(bis);
+      
+      HashMap map = StreamUtils.readMap(dais, true);
+      
+      dais.close();
+            
+      return map;
+   }
+   
+
+   //TODO - combine these
+   protected void incrementChannelCount(Message m, PreparedStatement ps) throws Exception
+   {
+      ps.setLong(1, m.getMessageID());
+   }
+         
+   protected void decrementChannelCount(Message m, PreparedStatement ps) throws Exception
+   {
+      ps.setLong(1, m.getMessageID());
+   }
+   
+   /**
+    * Stores the message in the MESSAGE table.
+    */
+   protected void storeMessage(Message m, PreparedStatement ps) throws Exception
+   {      
+      // physically insert the row in the database
+      // first set the fields from org.jboss.messaging.core.Routable
+      ps.setLong(1, m.getMessageID());
+      ps.setString(2, m.isReliable() ? "Y" : "N");
+      ps.setLong(3, m.getExpiration());
+      ps.setLong(4, m.getTimestamp());
+      ps.setByte(5, m.getPriority());
+      
+      //headers
+      byte[] bytes = mapToBytes(((MessageSupport) m).getHeaders());
+      if (bytes != null)
+      {
+         setBytes(ps, 6, bytes);
+      }
+      else
+      {
+         ps.setNull(6, Types.LONGVARBINARY);
+      }
+      
+      byte[] payload = m.getPayloadAsByteArray();
+      if (payload != null)
+      {
+         setBytes(ps, 7, payload);
+      }
+      else
+      {
+         ps.setNull(7, Types.LONGVARBINARY);
+      }
+      
+      //The number of channels that hold a reference to the message - initially always 1
+      ps.setInt(8, 1);     
+      
+      ps.setByte(9, m.getType());
+   }
+   
+   /**
+    * Removes the message from the MESSAGE table.
+    */
+   protected void removeMessage(Message message, PreparedStatement ps) throws Exception
+   {
+      // physically delete the row in the database
+      ps.setLong(1, message.getMessageID());      
+   }
+   
+   protected void setVarBinaryColumn(int column, PreparedStatement ps, byte[] bytes) throws Exception
+   {
+      if (usingTrailingByte)
+      {
+         // Sybase has the stupid characteristic of truncating all trailing in zeros
+         // in varbinary columns
+         // So we add an extra byte on the end when we store the varbinary data
+         // otherwise we might lose data
+         // http://jira.jboss.org/jira/browse/JBMESSAGING-825
+         
+         byte[] res = new byte[bytes.length + 1];
+         
+         System.arraycopy(bytes, 0, res, 0, bytes.length);
+         
+         res[bytes.length] = 127;
+
+         bytes = res;
+      }
+      
+      ps.setBytes(column, bytes);            
+      
+      if (trace) { log.trace("Setting varbinary column of length: " + bytes.length); }
+   }
+   
+   protected byte[] getVarBinaryColumn(ResultSet rs, int columnIndex) throws Exception
+   {
+      byte[] bytes = rs.getBytes(columnIndex);
+      
+      if (usingTrailingByte)
+      {
+         // Get rid of the trailing byte
+         
+         // http://jira.jboss.org/jira/browse/JBMESSAGING-825
+         
+         byte[] newBytes = new byte[bytes.length - 1];
+         
+         System.arraycopy(bytes, 0, newBytes, 0, bytes.length - 1);
+         
+         bytes = newBytes;
+      }
+      
+      return bytes;
+   }
+     
+   // Used for storing message headers and bodies
+   protected void setBytes(PreparedStatement ps, int columnIndex, byte[] bytes) throws Exception
+   {
+      if (usingBinaryStream)
+      {
+         //Set the bytes using a binary stream - likely to be better for large byte[]
+         
+         InputStream is = null;
+         
+         try
+         {
+            is = new ByteArrayInputStream(bytes);
+            
+            ps.setBinaryStream(columnIndex, is, bytes.length);
+         }
+         finally
+         {
+            if (is != null)
+            {
+               is.close();
+            }
+         }
+      }
+      else
+      {
+         //Set the bytes using setBytes() - likely to be better for smaller byte[]
+         
+         setVarBinaryColumn(columnIndex, ps, bytes);
+      }
+   }
+   
+   protected byte[] getBytes(ResultSet rs, int columnIndex) throws Exception
+   {
+      if (usingBinaryStream)
+      {
+         //Get the bytes using a binary stream - likely to be better for large byte[]
+         
+         InputStream is = null;
+         ByteArrayOutputStream os = null;
+         
+         final int BUFFER_SIZE = 4096;
+         
+         try
+         {
+            InputStream i = rs.getBinaryStream(columnIndex);
+            
+            if (i == null)
+            {
+               return null;
+            }
+            
+            is = new BufferedInputStream(rs.getBinaryStream(columnIndex), BUFFER_SIZE);
+            
+            os = new ByteArrayOutputStream(BUFFER_SIZE);
+            
+            int b;
+            while ((b = is.read()) != -1)
+            {
+               os.write(b);
+            }
+            
+            return os.toByteArray();
+         }
+         finally
+         {
+            if (is != null)
+            {
+               is.close();
+            }
+            if (os != null)
+            {
+               os.close();
+            }
+         }
+      }
+      else
+      {
+         //Get the bytes using getBytes() - better for smaller byte[]
+         return getVarBinaryColumn(rs, columnIndex);
+      }
+   }
+   
+   protected void getLocks(List refs)
+   {
+      Iterator iter = refs.iterator();
+      while (iter.hasNext())
+      {
+         MessageReference ref = (MessageReference)iter.next();
+         Message m = ref.getMessage();
+         LockMap.instance.obtainLock(m);        
+      }
+   }
+   
+   protected void releaseLocks(List refs)
+   {
+      Iterator iter = refs.iterator();
+      while (iter.hasNext())
+      {
+         MessageReference ref = (MessageReference)iter.next();
+         Message m = ref.getMessage();
+         LockMap.instance.releaseLock(m);         
+      }
+   }
+   
+   protected void logBatchUpdate(String name, int[] rows, String action)
+   {
+      int count = 0;
+      for (int i = 0; i < rows.length; i++)
+      {
+         count += rows[i];
+      }
+      log.trace("Batch update " + name + ", " + action + " total of " + count + " rows");
+   }
+   
+   protected int updateWithRetry(PreparedStatement ps) throws Exception
+   {
+      return updateWithRetry(ps, false)[0];
+   }
+   
+   protected int[] updateWithRetryBatch(PreparedStatement ps) throws Exception
+   {
+      return updateWithRetry(ps, true);
+   }
+   
+   //PersistentServiceSupport overrides ----------------------------
+   
+   protected Map getDefaultDDLStatements()
+   {
+      Map map = new LinkedHashMap();
+      //Message reference
+      map.put("CREATE_MESSAGE_REFERENCE",
+              "CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, " +
+              "MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, " +
+              "DELIVERY_COUNT INTEGER, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))");
+      map.put("CREATE_IDX_MESSAGE_REF_TX", "CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)");
+      map.put("CREATE_IDX_MESSAGE_REF_ORD", "CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)");
+      map.put("CREATE_IDX_MESSAGE_REF_PAGE_ORD", "CREATE INDEX JBM_MSG_REF__PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)");
+      map.put("CREATE_IDX_MESSAGE_REF_MESSAGE_ID", "CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)");      
+      map.put("CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY", "CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)");
+      //Message
+      map.put("CREATE_MESSAGE",
+              "CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), " +
+              "EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, HEADERS LONGVARBINARY, " +
+              "PAYLOAD LONGVARBINARY, CHANNEL_COUNT INTEGER, TYPE TINYINT, " +
+              "PRIMARY KEY (MESSAGE_ID))"); 
+      //Transaction
+      map.put("CREATE_TRANSACTION",
+              "CREATE TABLE JBM_TX (" +
+              "TRANSACTION_ID BIGINT, BRANCH_QUAL VARBINARY(254), " +
+              "FORMAT_ID INTEGER, GLOBAL_TXID VARBINARY(254), PRIMARY KEY (TRANSACTION_ID))");
+      //Counter
+      map.put("CREATE_COUNTER",
+              "CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))");
+      return map;
+   }
+      
+   protected Map getDefaultDMLStatements()
+   {                
+      Map map = new LinkedHashMap();
+      //Message reference
+      map.put("INSERT_MESSAGE_REF",
+              "INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) " +
+              "VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
+      map.put("DELETE_MESSAGE_REF", "DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'");
+      map.put("UPDATE_MESSAGE_REF",
+              "UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' " +
+              "WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'");
+      map.put("UPDATE_PAGE_ORDER", "UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?");
+      map.put("COMMIT_MESSAGE_REF1", "UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'");
+      map.put("COMMIT_MESSAGE_REF2", "DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'");
+      map.put("ROLLBACK_MESSAGE_REF1", "DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'");
+      map.put("ROLLBACK_MESSAGE_REF2", "UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'");
+      map.put("LOAD_PAGED_REFS",
+              "SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF " +
+              "WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD");
+      map.put("LOAD_UNPAGED_REFS",
+              "SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' " +
+              "AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD");
+      map.put("LOAD_REFS",
+              "SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' " +
+              "AND CHANNEL_ID = ? ORDER BY ORD");      
+      
+      map.put("UPDATE_REFS_NOT_PAGED", "UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?");       
+      map.put("SELECT_MIN_MAX_PAGE_ORD", "SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?");     
+      map.put("SELECT_EXISTS_REF_MESSAGE_ID", "SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?");
+      map.put("UPDATE_DELIVERY_COUNT", "UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?");
+      map.put("UPDATE_CHANNEL_ID", "UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?");
+      //Message
+      map.put("LOAD_MESSAGES",
+              "SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, " +
+              "PRIORITY, HEADERS, PAYLOAD, TYPE " +
+              "FROM JBM_MSG");
+      map.put("INSERT_MESSAGE",
+              "INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, " +
+              "TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) " +           
+              "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)" );
+      map.put("INC_CHANNEL_COUNT", "UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?");
+      map.put("DEC_CHANNEL_COUNT", "UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?");
+      map.put("DELETE_MESSAGE", "DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT = 0");
+      map.put("MESSAGE_ID_COLUMN", "MESSAGE_ID");
+      map.put("MESSAGE_EXISTS", "SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?");
+      //Transaction
+      map.put("INSERT_TRANSACTION",
+              "INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) " +
+              "VALUES(?, ?, ?, ?)");
+      map.put("DELETE_TRANSACTION", "DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?");
+      map.put("SELECT_PREPARED_TRANSACTIONS", "SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX");
+      map.put("SELECT_MESSAGE_ID_FOR_REF", "SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD");
+      map.put("SELECT_MESSAGE_ID_FOR_ACK", "SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD");
+      
+      //Counter
+      map.put("UPDATE_COUNTER", "UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?");
+      map.put("SELECT_COUNTER", "SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=?");
+      map.put("INSERT_COUNTER", "INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)");
+      //Other
+      map.put("SELECT_ALL_CHANNELS", "SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF");      
+      return map;
+   }
+   
+   // Private -------------------------------------------------------
+   
+
+   
+   private int[] updateWithRetry(PreparedStatement ps, boolean batch) throws Exception
+   {
+      final int MAX_TRIES = 25;      
+      
+      int rows = 0;
+      
+      int[] rowsArr = null;
+      
+      int tries = 0;
+      
+      while (true)
+      {
+         try
+         {
+            if (batch)
+            {
+               rowsArr = ps.executeBatch();
+            }
+            else
+            {
+               rows = ps.executeUpdate();
+            }
+            
+            if (tries > 0)
+            {
+               log.warn("Update worked after retry");
+            }
+            break;
+         }
+         catch (SQLException e)
+         {
+            log.warn("SQLException caught - assuming deadlock detected, try:" + (tries + 1), e);
+            tries++;
+            if (tries == MAX_TRIES)
+            {
+               log.error("Retried " + tries + " times, now giving up");
+               throw new IllegalStateException("Failed to update references");
+            }
+            log.warn("Trying again after a pause");
+            //Now we wait for a random amount of time to minimise risk of deadlock
+            Thread.sleep((long)(Math.random() * 500));
+         }  
+      }
+      
+      if (batch)
+      {
+         return rowsArr;
+      }
+      else
+      {
+         return new int[] { rows };
+      }
+   }
+   
+   private List getMessageChannelPair(String sqlQuery, long transactionId) throws Exception
+   {
+      if (trace) log.trace("loading message and channel ids for tx [" + transactionId + "]");
+      
+      Connection conn = null;
+      PreparedStatement ps = null;
+      ResultSet rs = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      try
+      {
+         conn = ds.getConnection();
+         
+         ps = conn.prepareStatement(sqlQuery);
+         
+         ps.setLong(1, transactionId);
+         
+         rs = ps.executeQuery();
+         
+         //Don't use a Map. A message could be in multiple channels in a tx, so if you use a map
+         //when you put the same message again it's going to overwrite the previous put!!
+         
+         List holders = new ArrayList();
+         
+         //Unique set of messages
+         Set msgIds = new HashSet();
+         
+         //TODO it would probably have been simpler just to have done all this in a SQL JOIN rather
+         //than do the join in memory.....
+         
+         class Holder
+         {
+            long messageId;
+            long channelId;
+            Holder(long messageId, long channelId)
+            {
+               this.messageId = messageId;
+               this.channelId = channelId;
+            }
+         }
+                  
+         while(rs.next())
+         {            
+            long messageId = rs.getLong(1);
+            long channelId = rs.getLong(2);
+            
+            Holder holder = new Holder(messageId, channelId);
+            
+            holders.add(holder);
+                        
+            msgIds.add(new Long(messageId));
+            
+            if (trace) log.trace("Loaded MsgID: " + messageId + " and ChannelID: " + channelId);
+         }
+         
+         Map messageMap = new HashMap();
+         
+         List messages = getMessages(new ArrayList(msgIds));
+         
+         for (Iterator iter = messages.iterator(); iter.hasNext(); )
+         {
+            Message msg = (Message)iter.next();
+            
+            messageMap.put(new Long(msg.getMessageID()), msg);            
+         }
+         
+         List returnList = new ArrayList();
+         
+         for (Iterator iter = holders.iterator(); iter.hasNext(); )
+         {
+            Holder holder = (Holder)iter.next();
+            
+            Message msg = (Message)messageMap.get(new Long(holder.messageId));
+            
+            if (msg == null)
+            {
+               throw new IllegalStateException("Cannot find message " + holder.messageId);
+            }
+            
+            MessageChannelPair pair = new MessageChannelPair(msg, holder.channelId);
+            
+            returnList.add(pair);
+         }
+         
+         return returnList;
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+      	closeResultSet(rs);
+      	closeStatement(ps);
+      	closeConnection(conn);
+         wrap.end();
+      }
+   }
+   
+   private synchronized long getOrdering()
+   {
+      //We generate the ordering for the message reference by taking the lowest 48 bits of the current time and
+      //concatenating with a 15 bit rotating counter to form a string of 63 bits which we then place
+      //in the right most bits of a long, giving a positive signed 63 bit integer.
+      
+      //Having a time element in the ordering means we don't have to maintain a counter in the database
+      //It also helps with failover since if two queues merge after failover then, the ordering will mean
+      //their orderings interleave nicely and they still get consumed in pretty much time order
+      
+      //We only have to guarantee ordering per session, so having slight differences of time on different nodes is
+      //not a problem
+      
+      //The time element is good for about 8919 years - if you're still running JBoss Messaging then, I suggest you need an
+      //upgrade!
+      
+      long order = System.currentTimeMillis();
+      
+      order = order << 15;
+      
+      order = order | orderCount;
+      
+      if (orderCount == Short.MAX_VALUE)
+      {
+         orderCount = 0;
+      }
+      else
+      {
+         orderCount++;
+      }
+      
+      return order;
+   }
+
+   // Inner classes -------------------------------------------------
+        
+   private static class ChannelRefPair
+   {
+      private long channelID;
+      private MessageReference ref;
+      
+      private ChannelRefPair(long channelID, MessageReference ref)
+      {
+         this.channelID = channelID;
+         this.ref = ref;
+      }
+   }
+   
+   private class TransactionCallback implements TxCallback
+   {
+      private Transaction tx;
+      
+      private List refsToAdd;
+      
+      private List refsToRemove;
+      
+      private TransactionCallback(Transaction tx)
+      {
+         this.tx = tx;
+         
+         refsToAdd = new ArrayList();
+         
+         refsToRemove = new ArrayList();
+      }
+      
+      private void addReferenceToAdd(long channelId, MessageReference ref)
+      {
+         refsToAdd.add(new ChannelRefPair(channelId, ref));
+      }
+      
+      private void addReferenceToRemove(long channelId, MessageReference ref)
+      {
+         refsToRemove.add(new ChannelRefPair(channelId, ref));
+      }
+      
+      public void afterCommit(boolean onePhase)
+      {
+         //NOOP
+      }
+      
+      public void afterPrepare()
+      {
+         //NOOP
+      }
+      
+      public void afterRollback(boolean onePhase)
+      {
+         //NOOP
+      }
+      
+      public void beforeCommit(boolean onePhase) throws Exception
+      {
+         if (onePhase)
+         {
+            handleBeforeCommit1PC(refsToAdd, refsToRemove, tx);
+         }
+         else
+         {
+            handleBeforeCommit2PC(refsToRemove, tx);
+         }
+      }
+      
+      public void beforePrepare() throws Exception
+      {
+         handleBeforePrepare(refsToAdd, refsToRemove, tx);
+      }
+      
+      public void beforeRollback(boolean onePhase) throws Exception
+      {
+         if (onePhase)
+         {
+            //NOOP - nothing in db
+         }
+         else
+         {
+            handleBeforeRollback(refsToAdd, tx);
+         }
+      }
+   }
+   
+   static class MessageOrderComparator implements Comparator
+   {
+      static MessageOrderComparator instance = new MessageOrderComparator();
+      
+      public int compare(Object o1, Object o2)
+      {        
+         MessageReference ref1 = (MessageReference)o1;
+         MessageReference ref2 = (MessageReference)o2;
+
+         long id1 = ref1.getMessage().getMessageID();         
+         long id2 = ref2.getMessage().getMessageID(); 
+         
+         return (id1 < id2 ? -1 : (id1 == id2 ? 0 : 1));
+      }      
+   }
+   
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/JDBCSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/JDBCSupport.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/JDBCSupport.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,361 @@
+/*
+ * 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.impl;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.sql.DataSource;
+import javax.transaction.Status;
+import javax.transaction.TransactionManager;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.contract.MessagingComponent;
+
+/**
+ * Common functionality for messaging components that need to access a database.
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 2726 $</tt>
+ *
+ * $Id: JDBCSupport.java 2726 2007-05-24 19:25:06Z timfox $
+ *
+ */
+public class JDBCSupport implements MessagingComponent
+{
+   private static final Logger log = Logger.getLogger(JDBCSupport.class);
+   
+   private static boolean trace = log.isTraceEnabled();
+      
+   protected DataSource ds;
+   
+   private TransactionManager tm;
+      
+   protected Properties sqlProperties;
+         
+   private Map defaultDMLStatements;
+   
+   private Map defaultDDLStatements;
+       
+   private boolean createTablesOnStartup = true;
+      
+   public JDBCSupport()
+   {
+      defaultDMLStatements = new LinkedHashMap();
+      
+      defaultDDLStatements = new LinkedHashMap();
+      
+      sqlProperties = new Properties();
+   }
+   
+   public JDBCSupport(DataSource ds, TransactionManager tm, Properties sqlProperties,
+                      boolean createTablesOnStartup)
+   {
+      this();
+      
+      this.ds = ds;
+      
+      this.tm = tm;
+      
+      if (sqlProperties != null)
+      {
+         this.sqlProperties = sqlProperties;
+      }
+      
+      this.createTablesOnStartup = createTablesOnStartup;
+   }
+      
+   // MessagingComponent overrides ---------------------------------
+   
+   public void start() throws Exception
+   {
+      defaultDMLStatements.putAll(getDefaultDMLStatements());
+      
+      defaultDDLStatements.putAll(getDefaultDDLStatements());
+
+      // Make a copy without startup statements
+      Properties sqlPropertiesCopy = new Properties();
+
+      for (Iterator iterSQL = sqlProperties.entrySet().iterator(); iterSQL.hasNext();)
+      {
+         Map.Entry entry = (Map.Entry) iterSQL.next();
+         if (!this.ignoreVerificationOnStartup((String)entry.getKey()))
+         {
+            sqlPropertiesCopy.put(entry.getKey(), entry.getValue());
+         }
+      }
+
+      //Validate the SQL properties
+      Iterator iter = sqlPropertiesCopy.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 (!sqlPropertiesCopy.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 SQL properties");
+            }
+         }
+         
+         iter = defaultDDLStatements.keySet().iterator();
+         
+         while (iter.hasNext())
+         {
+            String statementName = (String)iter.next();
+            
+            if (sqlPropertiesCopy.get(statementName) == null)
+            {
+               throw new IllegalStateException("SQL statement " + statementName + " is not specified in the SQL properties");
+            }
+         }
+      }
+      
+      if (createTablesOnStartup)
+      {
+         createSchema();
+      }
+      
+      log.debug(this + " started");      
+   }
+   public void stop() throws Exception
+   {
+      log.debug(this + " stopped");
+   }
+   
+   // 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);
+      }
+      
+      return sqlProperties.getProperty(statementName, defaultStatement);
+   }
+   
+   protected Map getDefaultDMLStatements()
+   {                
+      return Collections.EMPTY_MAP;
+   }
+   
+   protected Map getDefaultDDLStatements()
+   {
+      return Collections.EMPTY_MAP;
+   }
+
+   /** Subclasses might choose to not cross check the maps on certain statements.
+    *  An example would be POPULATE.TABLES on JDBCJMSUserManagerService */
+   protected boolean ignoreVerificationOnStartup(String statementName)
+   {
+      return false;
+   }
+   
+   protected void closeResultSet(ResultSet rs)
+   {
+   	if (rs != null)
+      {
+         try
+         {
+            rs.close();
+         }
+         catch (Throwable e)
+         {
+         	if (trace)
+         	{
+         		log.trace("Failed to close result set", e);
+         	}
+         }
+      }
+   }
+   
+   protected void closeStatement(Statement st)
+   {
+   	if (st != null)
+      {
+         try
+         {
+         	st.close();
+         }
+         catch (Throwable e)
+         {
+         	if (trace)
+         	{
+         		log.trace("Failed to close statement", e);
+         	}
+         }
+      }
+   }
+   
+   protected void closeConnection(Connection conn)
+   {
+   	if (conn != null)
+      {
+         try
+         {
+         	conn.close();
+         }
+         catch (Throwable e)
+         {
+         	if (trace)
+         	{
+         		log.trace("Failed to close statement", e);
+         	}
+         }
+      }
+   }
+   // Private ----------------------------------------------------------------
+              
+   private void createSchema() throws Exception
+   {      
+      // Postgresql will not process any further commands in a transaction after a create table
+      // fails: org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands
+      // ignored until end of transaction block. Therefore we need to ensure each CREATE is executed
+      // in its own transaction
+                              
+      for (Iterator i = defaultDDLStatements.keySet().iterator(); i.hasNext(); )
+      {
+         Connection conn = null;      
+         
+         Statement st = null;
+                  
+         TransactionWrapper tx = new TransactionWrapper();
+                  
+         try
+         {                        
+            conn = ds.getConnection();
+                        
+            String statementName = (String)i.next();
+             
+            String statement = getSQLStatement(statementName);
+            
+            if (!"IGNORE".equals(statement))
+            {               
+               try
+               {
+                  if (log.isTraceEnabled()) { log.trace("Executing: " + statement); }
+                      
+                  st = conn.createStatement();
+                  
+                  st.executeUpdate(statement);
+               }
+               catch (Exception e) 
+               {
+                  log.debug("Failed to execute: " + statement, e);
+                  
+                  tx.exceptionOccurred();
+               }  
+            }
+         }
+         finally
+         {
+         	closeStatement(st);
+         	
+            closeConnection(conn);
+            
+            tx.end();
+         } 
+      }                 
+   }      
+   
+   // Innner classes ---------------------------------------------------------
+   
+   protected class TransactionWrapper
+   {
+      private javax.transaction.Transaction oldTx;
+      
+      private boolean failed;
+      
+      public TransactionWrapper() throws Exception
+      {
+         oldTx = tm.suspend();
+         
+         tm.begin();
+      }
+      
+      public void end() throws Exception
+      {
+         try
+         {
+            if (Status.STATUS_MARKED_ROLLBACK == tm.getStatus())
+            {
+               failed = true;
+               if (trace) { log.trace("Rolling back tx"); }
+               tm.rollback();               
+            }
+            else
+            {
+               if (trace) { log.trace("Committing tx"); }
+               tm.commit();
+            }
+         }
+         finally
+         {
+            if (oldTx != null && tm != null)
+            {
+               if (trace) { log.trace("Resuming tx"); }
+               tm.resume(oldTx);
+            }
+         }
+      }      
+      
+      public void exceptionOccurred() throws Exception
+      {
+         tm.setRollbackOnly();
+      }
+      
+      public boolean isFailed()
+      {
+         return failed;
+      }
+   }
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/MessagingQueue.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/MessagingQueue.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/MessagingQueue.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,424 @@
+/*
+  * 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.impl;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.DeliveryObserver;
+import org.jboss.messaging.core.contract.Distributor;
+import org.jboss.messaging.core.contract.Filter;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.PersistenceManager;
+import org.jboss.messaging.core.contract.Queue;
+import org.jboss.messaging.core.contract.Receiver;
+import org.jboss.messaging.core.impl.clusterconnection.MessageSucker;
+import org.jboss.messaging.core.impl.tx.Transaction;
+
+/**
+ * 
+ * A MessagingQueue
+ * 
+ * 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: 1295 $</tt>
+ *
+ * $Id: Queue.java 1295 2006-09-15 17:44:02Z timfox $
+ *
+ */
+public class MessagingQueue extends PagingChannelSupport implements Queue
+{
+   // Constants -----------------------------------------------------
+   
+   // Static --------------------------------------------------------
+	
+	private static final Logger log = Logger.getLogger(MessagingQueue.class);
+      
+   // Attributes ----------------------------------------------------
+   
+   private int nodeID;
+   
+   protected String name;
+   
+   protected Filter filter;
+   
+   protected boolean clustered;
+   
+   protected Distributor remoteDistributor;
+   
+   protected Distributor localDistributor;
+
+   private boolean trace = log.isTraceEnabled();
+   
+   private Set suckers;
+   
+   private boolean handleFlowControlForConsumers;
+   
+   private boolean preserveOrdering;
+            
+   // Constructors --------------------------------------------------
+       
+   public MessagingQueue(int nodeID, String name, long id, MessageStore ms, PersistenceManager pm,             
+                         boolean recoverable, int maxSize, Filter filter,
+                         int fullSize, int pageSize, int downCacheSize, boolean clustered,
+                         boolean preserveOrdering)
+   {
+      super(id, ms, pm, recoverable, maxSize, fullSize, pageSize, downCacheSize);
+      
+      setup(nodeID, name, filter, clustered, preserveOrdering);
+   }
+   
+   /** This constructor is used when loading queue from storage - the paging params, maxSize and preserveOrdering don't matter
+    * they are injected when the queue or topic service is started
+    */
+   public MessagingQueue(int nodeID, String name, long id, MessageStore ms, PersistenceManager pm,             
+					          boolean recoverable, Filter filter,
+					          boolean clustered)
+	{
+		super(id, ms, pm, recoverable, -1, 100000, 2000, 2000); //paging params etc are actually ignored
+		
+		setup(nodeID, name, filter, clustered, false);
+	}
+   
+   /* This constructor is only used in tests - should we remove it? */
+   public MessagingQueue(int nodeID, String name, long id, MessageStore ms, PersistenceManager pm,             
+   		                boolean recoverable, int maxSize, Filter filter, boolean clustered,
+   		                boolean preserveOrdering)
+   {
+   	super(id, ms, pm, recoverable, maxSize);
+
+   	setup(nodeID, name, filter, clustered, preserveOrdering);
+   }
+   
+   /* Constructor for a remote queue representation in a cluster */
+   public MessagingQueue(int nodeID, String name, long id, boolean recoverable,
+   		                Filter filter, boolean clustered)
+   {
+   	super(id, null, null, recoverable, -1);
+   	
+   	setup(nodeID, name, filter, clustered, false);   	
+   }
+   
+   private void setup(int nodeID, String name, Filter filter, boolean clustered, boolean preserveOrdering)
+   {
+   	this.nodeID = nodeID;
+
+   	this.name = name;
+
+   	this.filter = filter;
+
+   	this.clustered = clustered;
+   	
+   	this.preserveOrdering = preserveOrdering;
+   	
+   	localDistributor = new DistributorWrapper(new RoundRobinDistributor());
+   	
+   	remoteDistributor = new DistributorWrapper(new RoundRobinDistributor());
+   	
+   	distributor = new ClusterRoundRobinDistributor(localDistributor, remoteDistributor, preserveOrdering);
+   	
+   	suckers = new HashSet();
+   }
+   
+   // Queue implementation
+   // ---------------------------------------------------------------
+      
+   public int getNodeID()
+   {
+   	return nodeID;
+   }
+   
+   public String getName()
+   {
+      return name;
+   }
+      
+   public Filter getFilter()
+   {
+      return filter;
+   }
+   
+   public boolean isClustered()
+   {
+      return clustered;
+   }
+   
+   public Distributor getLocalDistributor()
+   {
+   	return localDistributor;
+   }
+   
+   public Distributor getRemoteDistributor()
+   {
+   	return remoteDistributor;
+   }
+   
+   /**
+    * Merge the contents of one queue with another - this happens at failover when a queue is failed
+    * over to another node, but a queue with the same name already exists. In this case we merge the
+    * two queues.
+    */
+   public void mergeIn(long channelID) throws Exception
+   {
+      if (trace) { log.trace("Merging queue " + channelID + " into " + this); }
+           
+      synchronized (lock)
+      {
+         flushDownCache();
+                  
+         PersistenceManager.InitialLoadInfo ili =
+            pm.mergeAndLoad(channelID, channelID, fullSize - messageRefs.size(),
+                            firstPagingOrder, nextPagingOrder);
+            
+         if (trace) { log.trace("Loaded " + ili.getRefInfos().size() + " refs"); }            
+
+         doLoad(ili);         
+         
+         deliverInternal();
+      }
+   }
+   
+   public void registerSucker(MessageSucker sucker)
+   {
+   	if (trace) { log.trace(this + " Registering sucker " + sucker); }
+   	
+   	synchronized (lock)
+   	{
+   		if (!suckers.contains(sucker))
+   		{
+   			suckers.add(sucker);
+	   	
+   			handleFlowControlForConsumers = true;
+   			
+   			if (getReceiversReady())
+   			{   				
+   				if (trace) { log.trace(this + " receivers ready so setting consumer to true"); }
+   			
+   				sucker.setConsuming(true);
+   			}
+   		}
+   	}
+   }
+   
+   public boolean unregisterSucker(MessageSucker sucker)
+   {
+   	synchronized (lock)
+   	{
+	   	boolean removed = suckers.remove(sucker);
+	   	
+	   	if (removed)
+	   	{
+	   		handleFlowControlForConsumers = false;
+	   	}
+	   	
+	   	return removed;
+   	}
+   }
+   
+   public int getFullSize()
+   {
+   	return fullSize;
+   }
+   
+   public int getPageSize()
+   {
+   	return pageSize;
+   }
+   
+   public int getDownCacheSize()
+   {
+   	return downCacheSize;
+   }
+   
+   public boolean isPreserveOrdering()
+   {
+   	return this.preserveOrdering;
+   }
+   
+   public void setPreserveOrdering(boolean preserveOrdering)
+   {
+      this.preserveOrdering = preserveOrdering;   	
+   }
+   
+   // ChannelSupport overrides --------------------------------------
+   
+   protected void deliverInternal()
+	{
+		super.deliverInternal();
+		
+		if (trace) { log.trace(this + " deliverInternal"); }
+   			
+		if (handleFlowControlForConsumers && getReceiversReady() && localDistributor.getNumberOfReceivers() > 0)
+		{
+			//The receivers are still ready for more messages but there is nothing left in the local queue
+			//so we inform the message suckers to start consuming (if they aren't already)
+			informSuckers(true);
+		}
+	}
+   
+   protected void setReceiversReady(boolean receiversReady)
+   {
+   	if (trace) { log.trace(this + " setReceiversReady " + receiversReady); }
+   	
+   	this.receiversReady = receiversReady;
+   	
+   	if (handleFlowControlForConsumers && receiversReady == false)
+   	{
+   		//No receivers are ready to accept message so tell the suckers to stop consuming
+   		informSuckers(false);
+   	}
+   }
+      
+   // Public --------------------------------------------------------
+   
+   public String toString()
+   {
+      return "Queue[" + nodeID + "/" + channelID + "-" + name +  "]";
+   }
+   
+   public boolean equals(Object other)
+   {
+   	if (!(other instanceof MessagingQueue))
+   	{
+   		return false;
+   	}
+   	
+   	MessagingQueue queue = (MessagingQueue)other;
+   	
+   	return (this.nodeID == queue.nodeID && this.name.equals(queue.name));
+   }
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   private void informSuckers(boolean consume)
+   {
+   	Iterator iter = suckers.iterator();
+   	
+   	while (iter.hasNext())
+   	{
+   		MessageSucker sucker = (MessageSucker)iter.next();
+   		
+   		sucker.setConsuming(consume);
+   	}
+   }
+   
+   // Inner classes -------------------------------------------------   
+   
+   protected class DistributorWrapper implements Distributor
+   {
+   	private Distributor distributor;
+   	
+   	protected DistributorWrapper(Distributor distributor)
+   	{
+   		this.distributor = distributor;
+   	}
+
+		public Delivery handle(DeliveryObserver observer, MessageReference reference, Transaction tx)
+		{
+			return distributor.handle(observer, reference, tx);
+		}
+
+		public boolean add(Receiver receiver)
+		{
+			if (trace) { log.trace(this + " attempting to add receiver " + receiver); }
+	      
+	      synchronized (lock)
+	      {	
+		      boolean added = distributor.add(receiver);
+		
+		      if (trace) { log.trace("receiver " + receiver + (added ? "" : " NOT") + " added"); }
+		
+		      setReceiversReady(true);
+		      		
+		      return added;
+	      }
+		}
+
+		public void clear()
+		{
+			synchronized (lock)
+	   	{
+	   		distributor.clear();
+	   	}
+		}
+
+		public boolean contains(Receiver receiver)
+		{
+	      synchronized (lock)
+	      {
+	      	return distributor.contains(receiver);
+	      }
+		}
+
+		public int getNumberOfReceivers()
+		{
+			synchronized (lock)
+	   	{
+	   		return distributor.getNumberOfReceivers();
+	   	}
+		}
+
+		public Iterator iterator()
+		{
+			synchronized (lock)
+	   	{
+	   		return distributor.iterator();
+	   	}
+		}
+
+		public boolean remove(Receiver receiver)
+		{
+			synchronized (lock)
+	   	{	   	
+		      boolean removed = distributor.remove(receiver);
+		      
+		      if (removed)
+		      {
+		      	if (localDistributor.getNumberOfReceivers() == 0)
+			      {
+			      	//Stop pulling from other queues into this one.
+			      	informSuckers(false);
+			      	
+			      	if (remoteDistributor.getNumberOfReceivers() == 0)
+				      {
+				         setReceiversReady(false);         
+				      }
+			      }
+		      }		     
+		
+		      if (trace) { log.trace(this + (removed ? " removed " : " did NOT remove ") + receiver); }
+		
+		      return removed;
+	   	}
+		}   	
+   }
+}

Copied: trunk/src/main/org/jboss/messaging/core/impl/PagingChannelSupport.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/PagingChannelSupport.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/PagingChannelSupport.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/PagingChannelSupport.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,598 @@
+/*
+ * 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.impl;
+
+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.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.PersistenceManager;
+import org.jboss.messaging.core.contract.PersistenceManager.InitialLoadInfo;
+import org.jboss.messaging.core.contract.PersistenceManager.ReferenceInfo;
+
+/**
+ * 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$</tt>
+ *
+ * $Id$
+ */
+public abstract class PagingChannelSupport extends ChannelSupport
+{
+   private static final Logger log = Logger.getLogger(PagingChannelSupport.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 = 200000;
+
+   /**
+    * The maximum number of references to load from storage in one go when unpaging
+    */
+   protected int pageSize = 2000;
+
+   /**
+    * The maximum number of references paged to storage in one operation
+    */
+   protected int downCacheSize = 2000;
+
+   /**
+    * 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;
+   
+   /**
+    * Constructor with default paging params.
+    */
+   public PagingChannelSupport(long channelID, MessageStore ms, PersistenceManager pm,
+                               boolean recoverable, int maxSize)
+   {
+      super(channelID, ms, pm, recoverable, maxSize);
+      
+      downCache = new ArrayList(downCacheSize);    
+   }
+   
+   /**
+    * Constructor specifying paging params.
+    */
+   public PagingChannelSupport(long channelID, MessageStore ms, PersistenceManager pm,
+                               boolean recoverable, int maxSize,
+                               int fullSize, int pageSize, int downCacheSize)
+   {
+      super(channelID, ms, pm, recoverable, maxSize);
+      
+      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;
+   }
+    
+   // Receiver implementation ----------------------------------------------------------------------
+
+   // Channel implementation -----------------------------------------------------------------------
+
+   public int getMessageCount()
+   {   
+      int count = super.getMessageCount();
+      
+      // Also need to add the paged refs
+      
+      synchronized (lock)
+      {      
+         count += nextPagingOrder - firstPagingOrder;
+      }
+      
+      return count;
+   }
+   
+   // Public ---------------------------------------------------------------------------------------
+
+   //Only used in testing
+   public int downCacheCount()
+   {
+      synchronized (lock)
+      {
+         return downCache.size();
+      }
+   }
+
+   //Only used in testing
+   public boolean isPaging()
+   {
+      synchronized (lock)
+      {
+         return paging;
+      }
+   }
+   
+   public void setPagingParams(int fullSize, int pageSize, int downCacheSize)
+   {
+      synchronized (lock)
+      { 
+         if (active)
+         {
+            throw new IllegalStateException("Cannot set paging params when active");
+         }
+         
+         this.fullSize = fullSize;
+         
+         this.pageSize = pageSize;
+         
+         this.downCacheSize = downCacheSize;         
+      }
+   }
+   
+   public void load() throws Exception
+   {            
+      synchronized (lock)
+      {
+         if (active)
+         {
+            throw new IllegalStateException("Cannot load channel when active");
+         }
+         
+         if (trace) { log.trace(this + " loading channel state"); }
+         
+         unload();
+         
+         //Load the unpaged references
+         InitialLoadInfo ili = pm.loadFromStart(channelID, fullSize);
+         
+         doLoad(ili);
+         
+         //Maybe we need to load some paged refs
+         
+         while (checkLoad()) {}
+      }
+   }
+   
+   
+   
+      
+   public void unload() throws Exception
+   {
+      synchronized (lock)
+      {
+         if (active)
+         {
+            throw new IllegalStateException("Cannot unload channel when active");
+         }
+         
+         messageRefs.clear();
+         
+         downCache.clear();
+         
+         paging = false;
+         
+         firstPagingOrder = nextPagingOrder = 0;  
+         
+         clearAllScheduledDeliveries();
+      }
+   }
+   
+   
+   // Protected ------------------------------------------------------------------------------------
+   
+   protected void loadPagedReferences(int 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();
+      
+      int unreliableNumber = 0;
+
+      Iterator iter = refInfos.iterator();
+      while (iter.hasNext())
+      {
+         ReferenceInfo info = (ReferenceInfo)iter.next();
+         
+         MessageReference ref = addFromRefInfo(info, refMap);
+         
+         if (recoverable && ref.getMessage().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);
+            
+            unreliableNumber++;
+         }
+      }
+      
+      if (!toRemove.isEmpty())
+      {
+         // Now we remove the references we loaded (only the non persistent or persistent in a non-recoverable store)
+         
+         pm.removeDepagedReferences(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.updateReferencesNotPagedInRange(channelID, firstPagingOrder, firstPagingOrder + number - 1, number - unreliableNumber);
+      }
+            
+      firstPagingOrder += number;
+      
+      if (firstPagingOrder == nextPagingOrder)
+      {
+         //No more refs in storage
+         firstPagingOrder = nextPagingOrder = 0;
+         
+         if (messageRefs.size() != fullSize)
+         {
+            paging = false;
+         }
+      }    
+   }
+      
+   protected void cancelInternal(MessageReference ref) throws Exception
+   {
+      synchronized (lock)
+      {         
+         super.cancelInternal(ref);
+         
+         if (paging)
+         {
+            // if paging and the in memory queue is exactly full we need to evict the end reference to storage to
+            // preserve the number of refs in the queue
+            if (messageRefs.size() == fullSize + 1)
+            {
+               MessageReference refCancel = (MessageReference)messageRefs.removeLast();
+    
+               addToDownCache(refCancel, true);
+            }
+         }
+               
+         if (trace) { log.trace(this + " added " + ref + " back into state"); }      
+      }
+   }
+      
+   protected MessageReference removeFirstInMemory() throws Exception
+   {
+      MessageReference result = super.removeFirstInMemory();
+
+      checkLoad();
+
+      return result;
+   }
+   
+   private boolean checkLoad() throws Exception
+   {
+      long refNum = nextPagingOrder - firstPagingOrder;
+      
+      if (refNum > 0)
+      {
+         int numberLoadable = (int)Math.min(refNum, pageSize);
+         
+         if (messageRefs.size() <= fullSize - numberLoadable)
+         {
+            //This will flush the down cache too
+            loadPagedReferences(numberLoadable);
+            
+            return true;
+         }
+         else
+         {
+            return false;
+         }
+      }
+      else
+      {
+         paging = false;
+         
+         return false;
+      }
+   }
+    
+   protected void addReferenceInMemory(MessageReference ref) throws Exception
+   {     
+      if (paging)
+      {
+         addToDownCache(ref, false);
+      }
+      else
+      {
+         super.addReferenceInMemory(ref);
+         
+         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, boolean cancelling) 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
+
+      //If cancelling then the ref is supposed to go back on the front of the queue segment in storage
+      //so we set the page ordering to be firstPageOrdering - 1
+      //If not cancelling, then the ref should go on the end of the queue in storage so
+      //we set the page ordering to be nextPageOrdering
+      
+      if (cancelling)
+      {
+         ref.setPagingOrder(firstPagingOrder - 1);
+         
+         firstPagingOrder--;
+      }
+      else
+      {
+         ref.setPagingOrder(nextPagingOrder);
+         
+         nextPagingOrder++;
+      }
+      
+      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();
+      
+      while (iter.hasNext())
+      {
+         MessageReference ref = (MessageReference) iter.next();
+           
+         if (ref.getMessage().isReliable() && recoverable)
+         {
+            toUpdate.add(ref);
+         }
+         else
+         {
+            toAdd.add(ref);
+         }
+      }
+      
+      if (!toAdd.isEmpty())
+      {
+         pm.pageReferences(channelID, toAdd, true);
+      }
+      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 (trace) { log.trace(this + " cleared downcache"); }
+   }
+   
+
+   
+   protected void doLoad(InitialLoadInfo ili) throws Exception
+   {
+      if (ili.getMaxPageOrdering() != null)            
+      {
+         firstPagingOrder = ili.getMinPageOrdering().longValue();
+         
+         nextPagingOrder = ili.getMaxPageOrdering().longValue() + 1;
+                           
+         paging = true;
+      }
+      else
+      {
+         firstPagingOrder = nextPagingOrder = 0;
+         
+         paging = false;
+      }
+      
+      Map refMap = processReferences(ili.getRefInfos());
+      
+      Iterator iter = ili.getRefInfos().iterator();
+      while (iter.hasNext())
+      {
+         ReferenceInfo info = (ReferenceInfo)iter.next();
+         
+         addFromRefInfo(info, refMap);
+      }
+   }
+        
+   // Private --------------------------------------------------------------------------------------
+   
+   protected 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);
+      
+      ref.setScheduledDeliveryTime(info.getScheduledDelivery());
+      
+      //Schedule the delivery if necessary, or just add to the in memory queue
+      if (!checkAndSchedule(ref))
+      {
+         messageRefs.addLast(ref, ref.getMessage().getPriority());
+      }
+      
+      return ref;
+   }
+   
+
+   protected 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;
+   }  
+  
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/RoundRobinDistributor.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/RoundRobinDistributor.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/RoundRobinDistributor.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,231 @@
+/*
+  * 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.impl;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.DeliveryObserver;
+import org.jboss.messaging.core.contract.Distributor;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.Receiver;
+import org.jboss.messaging.core.impl.tx.Transaction;
+
+/**
+ *  
+ * The distributor 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 FirstReceiverDistributor and is better
+ * suited when batching messages to consumers since we will end up with messages interleaved amongst
+ * consumers rather than in contiguous blocks.
+ *  
+ * @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 $</tt>
+ * $Id: $
+ */
+public class RoundRobinDistributor implements Distributor
+{
+   // Constants ------------------------------------------------------------------------------------
+
+   private static final Logger log = Logger.getLogger(RoundRobinDistributor.class);
+
+   // Static ---------------------------------------------------------------------------------------
+   
+   // Attributes -----------------------------------------------------------------------------------
+   
+   private boolean trace = log.isTraceEnabled();
+
+   // it's important that we're actually using an ArrayList for fast array access
+   private ArrayList receivers;
+   
+   private int target;
+   
+   private volatile boolean makeCopy;
+   
+   private ArrayList receiversCopy;
+   
+   // Constructors ---------------------------------------------------------------------------------
+
+   public RoundRobinDistributor()
+   {
+      receivers = new ArrayList();
+      
+      target = 0;
+      
+      makeCopy = true;
+   }
+
+   // Distributor implementation ------------------------------------------------------------------------
+   
+   public Delivery handle(DeliveryObserver observer, MessageReference ref, Transaction tx)
+   {             
+      if (makeCopy)
+      {
+         synchronized (this)
+         {         
+            // We make a copy of the receivers to avoid a race condition:
+            // http://jira.jboss.org/jira/browse/JBMESSAGING-505
+            // Note that we do not make a copy every time - only when the receivers have changed
+         
+            receiversCopy = new ArrayList(receivers);
+            
+            if (target >= receiversCopy.size())
+            {
+               target = 0;
+            }
+         
+            makeCopy = false;
+         }
+      }      
+      
+      if (receiversCopy.isEmpty())
+      {
+         return null;
+      }
+
+      Delivery del = null;
+      
+      boolean selectorRejected = false;
+      
+      int initial = target;
+
+      while (true)
+      {
+         Receiver r = (Receiver)receiversCopy.get(target);
+
+         try
+         {
+            Delivery d = r.handle(observer, ref, tx);
+
+            if (trace) { log.trace("receiver " + r + " handled " + ref + " and returned " + d); }
+            
+            if (d != null)
+            {
+               if (d.isSelectorAccepted())
+               {
+                  // deliver to the first receiver that accepts
+                  del = d;
+                  
+                  incTarget();
+                                                     
+                  break;
+               }
+               else
+               {
+                  selectorRejected = true;
+               }
+            }
+         }
+         catch(Throwable t)
+         {
+            // broken receiver - log the exception and ignore it
+            log.error("The receiver " + r + " is broken", t);
+         }
+
+         incTarget();
+
+         // if we've tried them all then we break
+         if (target == initial)
+         {
+            break;
+         }
+      }
+
+      if (del == null && selectorRejected)
+      {
+         del = new SimpleDelivery(null, null, false);
+      }
+
+      return del;      
+   }
+   
+   public synchronized boolean add(Receiver r)
+   {
+      if (receivers.contains(r))
+      {
+         return false;
+      }
+
+      receivers.add(r);
+      
+      makeCopy = true;
+      
+      return true;      
+   }
+
+   public synchronized boolean remove(Receiver r)
+   {
+      boolean removed = receivers.remove(r);
+      
+      if (removed)
+      {
+         makeCopy = true;
+      }
+      
+      return removed;      
+   }
+
+   public synchronized void clear()
+   {
+      receivers.clear();
+      
+      makeCopy = true;    
+   }
+
+   public synchronized boolean contains(Receiver r)
+   {
+      return receivers.contains(r);     
+   }
+
+   public synchronized Iterator iterator()
+   {
+      return receivers.iterator();      
+   }
+   
+   public synchronized int getNumberOfReceivers()
+   {
+      return receivers.size();      
+   }
+
+   // Public ---------------------------------------------------------------------------------------
+
+   // Package protected ----------------------------------------------------------------------------
+   
+   // Protected ------------------------------------------------------------------------------------
+
+   // Private --------------------------------------------------------------------------------------
+   
+   private void incTarget()
+   {
+      target++;
+      
+      if (target == receiversCopy.size())
+      {
+         target = 0;
+      }
+   }
+   
+   // Inner classes --------------------------------------------------------------------------------
+}
+

Copied: trunk/src/main/org/jboss/messaging/core/impl/SimpleDelivery.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/SimpleDelivery.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/SimpleDelivery.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/SimpleDelivery.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,121 @@
+/*
+  * 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.impl;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.DeliveryObserver;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.impl.tx.Transaction;
+
+/**
+ * A simple Delivery implementation.
+ *
+ * @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 SimpleDelivery implements Delivery
+{
+   // Constants ------------------------------------------------------------------------------------
+
+   // Static ---------------------------------------------------------------------------------------
+   
+   private static final Logger log = Logger.getLogger(SimpleDelivery.class);
+   
+   // Attributes -----------------------------------------------------------------------------------
+
+   private boolean selectorAccepted;
+   private DeliveryObserver observer;
+   private MessageReference reference;
+
+   private boolean trace = log.isTraceEnabled();
+
+   // Constructors ---------------------------------------------------------------------------------
+
+   public SimpleDelivery()
+   {
+      this(null, null);
+   }
+
+   public SimpleDelivery(DeliveryObserver observer, MessageReference reference)
+   {
+      this(observer, reference, true);
+   }
+
+   public SimpleDelivery(DeliveryObserver observer, MessageReference reference,
+                         boolean selectorAccepted)
+   {
+
+      this.reference = reference;
+      this.observer = observer;
+      this.selectorAccepted = selectorAccepted;
+   }
+
+   // Delivery implementation ----------------------------------------------------------------------
+
+   public MessageReference getReference()
+   {
+      return reference;
+   }
+   
+   public boolean isSelectorAccepted()
+   {
+      return selectorAccepted;
+   }
+
+   public DeliveryObserver getObserver()
+   {
+      return observer;
+   }
+
+   public void acknowledge(Transaction tx) throws Throwable
+   {        
+      if (trace) { log.trace(this + " acknowledging delivery " + ( tx == null ? "non-transactionally" : "in " + tx)); }
+      
+      observer.acknowledge(this, tx);
+   }
+
+   public void cancel() throws Throwable
+   {
+      if (trace) { log.trace(this + " cancelling delivery"); }
+         
+      observer.cancel(this);
+   }
+   
+   // Public ---------------------------------------------------------------------------------------
+
+   public String toString()
+   {
+      return "Delivery" + (reference == null ? "" : "[" + reference + "]");
+   }
+
+   // Package protected ----------------------------------------------------------------------------
+   
+   // Protected ------------------------------------------------------------------------------------
+   
+   // Private --------------------------------------------------------------------------------------
+   
+   // Inner classes --------------------------------------------------------------------------------
+}

Copied: trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory (from rev 2781, trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/jchannelfactory)

Deleted: trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/JChannelFactory.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/jchannelfactory/JChannelFactory.java	2007-06-13 18:15:18 UTC (rev 2781)
+++ trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/JChannelFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,15 +0,0 @@
-package org.jboss.messaging.core.plugin.postoffice.cluster.jchannelfactory;
-
-import org.jgroups.JChannel;
-
-/**
- * @author <a href="mailto:clebert.suconic at jboss.org">Clebert Suconic</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public interface JChannelFactory
-{
-   JChannel createSyncChannel() throws Exception;
-   JChannel createASyncChannel() throws Exception;
-}

Deleted: trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/MultiplexerJChannelFactory.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/jchannelfactory/MultiplexerJChannelFactory.java	2007-06-13 18:15:18 UTC (rev 2781)
+++ trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/MultiplexerJChannelFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,141 +0,0 @@
-/*
-   * JBoss, Home of Professional Open Source
-   * Copyright 2005, JBoss Inc., and individual contributors as indicated
-   * by the @authors tag. See the copyright.txt in the distribution for a
-   * full listing of individual contributors.
-   *
-   * This is free software; you can redistribute it and/or modify it
-   * under the terms of the GNU Lesser General Public License as
-   * published by the Free Software Foundation; either version 2.1 of
-   * the License, or (at your option) any later version.
-   *
-   * This software is distributed in the hope that it will be useful,
-   * but WITHOUT ANY WARRANTY; without even the implied warranty of
-   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   * Lesser General Public License for more details.
-   *
-   * You should have received a copy of the GNU Lesser General Public
-   * License along with this software; if not, write to the Free
-   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-   */
-
-package org.jboss.messaging.core.plugin.postoffice.cluster.jchannelfactory;
-
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import org.jgroups.JChannel;
-
-/**
- * A JChannelFactory that will use the MBean JChannelFactory interface
- *
- * @author <a href="mailto:clebert.suconic at jboss.org">Clebert Suconic</a>
- * @version <tt>$Revision$</tt>
- * $Id$
- */
-public class MultiplexerJChannelFactory implements JChannelFactory
-{
-
-   // Constants ------------------------------------------------------------------------------------
-
-   private static final String[] MUX_SIGNATURE = new String[]{"java.lang.String",
-      "java.lang.String", "boolean", "java.lang.String"};
-
-   // Attributes -----------------------------------------------------------------------------------
-   MBeanServer server;
-   ObjectName channelFactory;
-   String asyncStack;
-   String syncStack;
-   String uniqueID;
-   private static final String MUX_OPERATION = "createMultiplexerChannel";
-
-   // Static ---------------------------------------------------------------------------------------
-
-   // Constructors ---------------------------------------------------------------------------------
-
-   public MultiplexerJChannelFactory(MBeanServer server,
-                                    ObjectName channelFactory,
-                                    String uniqueID,
-                                    String syncStack,
-                                    String asyncStack)
-   {
-      this.server = server;
-      this.channelFactory = channelFactory;
-      this.uniqueID = uniqueID;
-      this.asyncStack = asyncStack;
-      this.syncStack = syncStack;
-   }
-
-   // Public ---------------------------------------------------------------------------------------
-
-   public MBeanServer getServer()
-   {
-      return server;
-   }
-
-   public void setServer(MBeanServer server)
-   {
-      this.server = server;
-   }
-
-   public ObjectName getChannelFactory()
-   {
-      return channelFactory;
-   }
-
-   public void setChannelFactory(ObjectName channelFactory)
-   {
-      this.channelFactory = channelFactory;
-   }
-
-   public String getAsyncStack()
-   {
-      return asyncStack;
-   }
-
-   public void setAsyncStack(String asyncStack)
-   {
-      this.asyncStack = asyncStack;
-   }
-
-   public String getSyncStack()
-   {
-      return syncStack;
-   }
-
-   public void setSyncStack(String syncStack)
-   {
-      this.syncStack = syncStack;
-   }
-
-   public String getUniqueID()
-   {
-      return uniqueID;
-   }
-
-   public void setUniqueID(String uniqueID)
-   {
-      this.uniqueID = uniqueID;
-   }
-
-   public JChannel createSyncChannel() throws Exception
-   {
-      return (JChannel) server.invoke(this.channelFactory, MUX_OPERATION,
-         new Object[]{syncStack, uniqueID, Boolean.TRUE, uniqueID}, MUX_SIGNATURE);
-   }
-
-   public JChannel createASyncChannel() throws Exception
-   {
-      return (JChannel) server.invoke(this.channelFactory, MUX_OPERATION,
-         new Object[]{asyncStack, uniqueID, Boolean.TRUE, uniqueID}, MUX_SIGNATURE);
-   }
-
-   // Package protected ----------------------------------------------------------------------------
-
-   // Protected ------------------------------------------------------------------------------------
-
-   // Private  -------------------------------------------------------------------------------------
-
-   // Inner classes  -------------------------------------------------------------------------------
-
-}

Copied: trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/MultiplexerJChannelFactory.java (from rev 2795, trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/jchannelfactory/MultiplexerJChannelFactory.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/MultiplexerJChannelFactory.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/MultiplexerJChannelFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,143 @@
+/*
+   * 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.impl.jchannelfactory;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.jboss.messaging.core.contract.JChannelFactory;
+import org.jgroups.JChannel;
+
+/**
+ * A JChannelFactory that will use the MBean JChannelFactory interface
+ *
+ * @author <a href="mailto:clebert.suconic at jboss.org">Clebert Suconic</a>
+ * @version <tt>$Revision$</tt>
+ * $Id$
+ */
+public class MultiplexerJChannelFactory implements JChannelFactory
+{
+
+   // Constants ------------------------------------------------------------------------------------
+
+   private static final String[] MUX_SIGNATURE = new String[]{"java.lang.String",
+      "java.lang.String", "boolean", "java.lang.String"};
+
+   // Attributes -----------------------------------------------------------------------------------
+   MBeanServer server;
+   ObjectName channelFactory;
+   String asyncStack;
+   String syncStack;
+   String uniqueID;
+   private static final String MUX_OPERATION = "createMultiplexerChannel";
+
+   // Static ---------------------------------------------------------------------------------------
+
+   // Constructors ---------------------------------------------------------------------------------
+
+   public MultiplexerJChannelFactory(MBeanServer server,
+                                    ObjectName channelFactory,
+                                    String uniqueID,
+                                    String syncStack,
+                                    String asyncStack)
+   {
+      this.server = server;
+      this.channelFactory = channelFactory;
+      this.uniqueID = uniqueID;
+      this.asyncStack = asyncStack;
+      this.syncStack = syncStack;
+   }
+
+   // Public ---------------------------------------------------------------------------------------
+
+   public MBeanServer getServer()
+   {
+      return server;
+   }
+
+   public void setServer(MBeanServer server)
+   {
+      this.server = server;
+   }
+
+   public ObjectName getChannelFactory()
+   {
+      return channelFactory;
+   }
+
+   public void setChannelFactory(ObjectName channelFactory)
+   {
+      this.channelFactory = channelFactory;
+   }
+
+   public String getAsyncStack()
+   {
+      return asyncStack;
+   }
+
+   public void setAsyncStack(String asyncStack)
+   {
+      this.asyncStack = asyncStack;
+   }
+
+   public String getSyncStack()
+   {
+      return syncStack;
+   }
+
+   public void setSyncStack(String syncStack)
+   {
+      this.syncStack = syncStack;
+   }
+
+   public String getUniqueID()
+   {
+      return uniqueID;
+   }
+
+   public void setUniqueID(String uniqueID)
+   {
+      this.uniqueID = uniqueID;
+   }
+
+   public JChannel createSyncChannel() throws Exception
+   {
+      return (JChannel) server.invoke(this.channelFactory, MUX_OPERATION,
+         new Object[]{syncStack, uniqueID, Boolean.TRUE, uniqueID}, MUX_SIGNATURE);
+   }
+
+   public JChannel createASyncChannel() throws Exception
+   {
+      return (JChannel) server.invoke(this.channelFactory, MUX_OPERATION,
+         new Object[]{asyncStack, uniqueID, Boolean.TRUE, uniqueID}, MUX_SIGNATURE);
+   }
+
+   // Package protected ----------------------------------------------------------------------------
+
+   // Protected ------------------------------------------------------------------------------------
+
+   // Private  -------------------------------------------------------------------------------------
+
+   // Inner classes  -------------------------------------------------------------------------------
+
+}

Deleted: trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/XMLJChannelFactory.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/jchannelfactory/XMLJChannelFactory.java	2007-06-13 18:15:18 UTC (rev 2781)
+++ trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/XMLJChannelFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,94 +0,0 @@
-/*
-   * JBoss, Home of Professional Open Source
-   * Copyright 2005, JBoss Inc., and individual contributors as indicated
-   * by the @authors tag. See the copyright.txt in the distribution for a
-   * full listing of individual contributors.
-   *
-   * This is free software; you can redistribute it and/or modify it
-   * under the terms of the GNU Lesser General Public License as
-   * published by the Free Software Foundation; either version 2.1 of
-   * the License, or (at your option) any later version.
-   *
-   * This software is distributed in the hope that it will be useful,
-   * but WITHOUT ANY WARRANTY; without even the implied warranty of
-   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   * Lesser General Public License for more details.
-   *
-   * You should have received a copy of the GNU Lesser General Public
-   * License along with this software; if not, write to the Free
-   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-   */
-
-package org.jboss.messaging.core.plugin.postoffice.cluster.jchannelfactory;
-
-import org.w3c.dom.Element;
-import org.jgroups.JChannel;
-
-/**
- * A JChannelFactory that will use Elements to create channels.
- * @author <a href="mailto:clebert.suconic at jboss.org">Clebert Suconic</a>
- * @version <tt>$Revision:1909 $</tt>
- * $Id:XMLJChannelFactory.java 1909 2007-01-06 06:08:03Z clebert.suconic at jboss.com $
- */
-public class XMLJChannelFactory implements JChannelFactory
-{
-
-   // Constants ------------------------------------------------------------------------------------
-
-   // Attributes -----------------------------------------------------------------------------------
-   Element syncConfig;
-   Element asyncConfig;
-
-   // Static ---------------------------------------------------------------------------------------
-
-   // Constructors ---------------------------------------------------------------------------------
-
-   public XMLJChannelFactory(Element syncConfig, Element asyncConfig)
-   {
-      this.syncConfig = syncConfig;
-      this.asyncConfig = asyncConfig;
-   }
-
-   // Public ---------------------------------------------------------------------------------------
-
-   public Element getSyncConfig()
-   {
-      return syncConfig;
-   }
-
-   public void setSyncConfig(Element syncConfig)
-   {
-      this.syncConfig = syncConfig;
-   }
-
-   public Element getAsyncConfig()
-   {
-      return asyncConfig;
-   }
-
-   public void setAsyncConfig(Element asyncConfig)
-   {
-      this.asyncConfig = asyncConfig;
-   }
-
-   // implementation of JChannelFactory ------------------------------------------------------------
-   public JChannel createSyncChannel() throws Exception
-   {
-      return new JChannel(syncConfig);
-   }
-
-   public JChannel createASyncChannel() throws Exception
-   {
-      return new JChannel(asyncConfig);
-   }
-
-   // Package protected ----------------------------------------------------------------------------
-
-   // Protected ------------------------------------------------------------------------------------
-
-   // Private --------------------------------------------------------------------------------------
-
-   // Inner classes --------------------------------------------------------------------------------
-
-}

Copied: trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/XMLJChannelFactory.java (from rev 2795, trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/jchannelfactory/XMLJChannelFactory.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/XMLJChannelFactory.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/jchannelfactory/XMLJChannelFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,95 @@
+/*
+   * JBoss, Home of Professional Open Source
+   * Copyright 2005, JBoss Inc., and individual contributors as indicated
+   * by the @authors tag. See the copyright.txt in the distribution for a
+   * full listing of individual contributors.
+   *
+   * This is free software; you can redistribute it and/or modify it
+   * under the terms of the GNU Lesser General Public License as
+   * published by the Free Software Foundation; either version 2.1 of
+   * the License, or (at your option) any later version.
+   *
+   * This software is distributed in the hope that it will be useful,
+   * but WITHOUT ANY WARRANTY; without even the implied warranty of
+   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   * Lesser General Public License for more details.
+   *
+   * You should have received a copy of the GNU Lesser General Public
+   * License along with this software; if not, write to the Free
+   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+   */
+
+package org.jboss.messaging.core.impl.jchannelfactory;
+
+import org.w3c.dom.Element;
+import org.jboss.messaging.core.contract.JChannelFactory;
+import org.jgroups.JChannel;
+
+/**
+ * A JChannelFactory that will use Elements to create channels.
+ * @author <a href="mailto:clebert.suconic at jboss.org">Clebert Suconic</a>
+ * @version <tt>$Revision:1909 $</tt>
+ * $Id:XMLJChannelFactory.java 1909 2007-01-06 06:08:03Z clebert.suconic at jboss.com $
+ */
+public class XMLJChannelFactory implements JChannelFactory
+{
+
+   // Constants ------------------------------------------------------------------------------------
+
+   // Attributes -----------------------------------------------------------------------------------
+   Element syncConfig;
+   Element asyncConfig;
+
+   // Static ---------------------------------------------------------------------------------------
+
+   // Constructors ---------------------------------------------------------------------------------
+
+   public XMLJChannelFactory(Element syncConfig, Element asyncConfig)
+   {
+      this.syncConfig = syncConfig;
+      this.asyncConfig = asyncConfig;
+   }
+
+   // Public ---------------------------------------------------------------------------------------
+
+   public Element getSyncConfig()
+   {
+      return syncConfig;
+   }
+
+   public void setSyncConfig(Element syncConfig)
+   {
+      this.syncConfig = syncConfig;
+   }
+
+   public Element getAsyncConfig()
+   {
+      return asyncConfig;
+   }
+
+   public void setAsyncConfig(Element asyncConfig)
+   {
+      this.asyncConfig = asyncConfig;
+   }
+
+   // implementation of JChannelFactory ------------------------------------------------------------
+   public JChannel createSyncChannel() throws Exception
+   {
+      return new JChannel(syncConfig);
+   }
+
+   public JChannel createASyncChannel() throws Exception
+   {
+      return new JChannel(asyncConfig);
+   }
+
+   // Package protected ----------------------------------------------------------------------------
+
+   // Protected ------------------------------------------------------------------------------------
+
+   // Private --------------------------------------------------------------------------------------
+
+   // Inner classes --------------------------------------------------------------------------------
+
+}

Copied: trunk/src/main/org/jboss/messaging/core/impl/memory (from rev 2781, trunk/src/main/org/jboss/messaging/core/memory)

Deleted: trunk/src/main/org/jboss/messaging/core/impl/memory/MemoryManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/memory/MemoryManager.java	2007-06-13 18:15:18 UTC (rev 2781)
+++ trunk/src/main/org/jboss/messaging/core/impl/memory/MemoryManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.memory;
-
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
-
-/**
- * A MemoryManager
-
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public interface MemoryManager extends MessagingComponent
-{
-   boolean isMemoryLow();    
-}

Deleted: trunk/src/main/org/jboss/messaging/core/impl/memory/SimpleMemoryManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/memory/SimpleMemoryManager.java	2007-06-13 18:15:18 UTC (rev 2781)
+++ trunk/src/main/org/jboss/messaging/core/impl/memory/SimpleMemoryManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,156 +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.memory;
-
-import org.jboss.logging.Logger;
-
-/**
- * A MemoryManager
-
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public class SimpleMemoryManager implements MemoryManager
-{
-   private static final Logger log = Logger.getLogger(SimpleMemoryManager.class);
-   
-   private static final long DEFAULT_MEASURE_INTERVAL = 3000;
-   
-   private static final int DEFAULT_FREE_MEMORY_PERCENT = 25;
-       
-   private Runtime runtime;
-   
-   //TODO Should be configurable
-   private long measureInterval;
-   
-   //TODO Should be configurable
-   private int freeMemoryPercent;
-   
-   private volatile boolean started;
-   
-   private Thread thread;
-   
-   private volatile boolean low;
-   
-   public SimpleMemoryManager()
-   {
-      runtime = Runtime.getRuntime();
-      
-      this.measureInterval = DEFAULT_MEASURE_INTERVAL;
-      
-      this.freeMemoryPercent = DEFAULT_FREE_MEMORY_PERCENT;    
-   }
-   
-   public boolean isMemoryLow()
-   {
-      return low;
-   }
-    
-   
-   public synchronized void start()
-   {
-      log.debug("Starting MemoryManager with MEASURE_INTERVAL: " + measureInterval
-               + " FREE_MEMORY_PERCENT: " + freeMemoryPercent);
-      
-      if (started)
-      {
-         //Already started
-         return;
-      }
-      
-      started = true;
-      
-      thread = new Thread(new MemoryRunnable());
-      
-      thread.setDaemon(true);
-      
-      thread.start();
-   }
-   
-   public synchronized void stop()
-   {      
-      if (!started)
-      {
-         //Already stopped
-         return;
-      }
-      
-      started = false;
-      
-      thread.interrupt();
-      
-      try
-      {
-         thread.join();
-      }
-      catch (InterruptedException ignore)
-      {         
-      }
-   }
-   
-   private class MemoryRunnable implements Runnable
-   {
-      public void run()
-      {
-         while (true)
-         {
-            try
-            {
-               if (thread.isInterrupted() && !started)
-               {
-                  break;
-               }
-               Thread.sleep(measureInterval);
-            }
-            catch (InterruptedException ignore)
-            {
-               if (!started)
-               {
-                  break;
-               }
-            }
-                        
-            long freeMemory = runtime.freeMemory();
-            
-            long maxMemory = runtime.maxMemory();
-            
-            long totalMemory = runtime.totalMemory();
-            
-            long availableMemory = freeMemory + maxMemory - totalMemory;
-            
-            if (100 * availableMemory / totalMemory <= freeMemoryPercent)
-            {
-               //log.warn("Less than " + freeMemoryPercent + "% of total available memory free");
-               low = true;
-            }
-            else
-            {
-               low = false;
-            }
-             
-         }
-      }
-   }
-}

Copied: trunk/src/main/org/jboss/messaging/core/impl/memory/SimpleMemoryManager.java (from rev 2795, trunk/src/main/org/jboss/messaging/core/memory/SimpleMemoryManager.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/memory/SimpleMemoryManager.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/memory/SimpleMemoryManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,157 @@
+/*
+ * 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.impl.memory;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.contract.MemoryManager;
+
+/**
+ * A MemoryManager
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ *
+ */
+public class SimpleMemoryManager implements MemoryManager
+{
+   private static final Logger log = Logger.getLogger(SimpleMemoryManager.class);
+   
+   private static final long DEFAULT_MEASURE_INTERVAL = 3000;
+   
+   private static final int DEFAULT_FREE_MEMORY_PERCENT = 25;
+       
+   private Runtime runtime;
+   
+   //TODO Should be configurable
+   private long measureInterval;
+   
+   //TODO Should be configurable
+   private int freeMemoryPercent;
+   
+   private volatile boolean started;
+   
+   private Thread thread;
+   
+   private volatile boolean low;
+   
+   public SimpleMemoryManager()
+   {
+      runtime = Runtime.getRuntime();
+      
+      this.measureInterval = DEFAULT_MEASURE_INTERVAL;
+      
+      this.freeMemoryPercent = DEFAULT_FREE_MEMORY_PERCENT;    
+   }
+   
+   public boolean isMemoryLow()
+   {
+      return low;
+   }
+    
+   
+   public synchronized void start()
+   {
+      log.debug("Starting MemoryManager with MEASURE_INTERVAL: " + measureInterval
+               + " FREE_MEMORY_PERCENT: " + freeMemoryPercent);
+      
+      if (started)
+      {
+         //Already started
+         return;
+      }
+      
+      started = true;
+      
+      thread = new Thread(new MemoryRunnable());
+      
+      thread.setDaemon(true);
+      
+      thread.start();
+   }
+   
+   public synchronized void stop()
+   {      
+      if (!started)
+      {
+         //Already stopped
+         return;
+      }
+      
+      started = false;
+      
+      thread.interrupt();
+      
+      try
+      {
+         thread.join();
+      }
+      catch (InterruptedException ignore)
+      {         
+      }
+   }
+   
+   private class MemoryRunnable implements Runnable
+   {
+      public void run()
+      {
+         while (true)
+         {
+            try
+            {
+               if (thread.isInterrupted() && !started)
+               {
+                  break;
+               }
+               Thread.sleep(measureInterval);
+            }
+            catch (InterruptedException ignore)
+            {
+               if (!started)
+               {
+                  break;
+               }
+            }
+                        
+            long freeMemory = runtime.freeMemory();
+            
+            long maxMemory = runtime.maxMemory();
+            
+            long totalMemory = runtime.totalMemory();
+            
+            long availableMemory = freeMemory + maxMemory - totalMemory;
+            
+            if (100 * availableMemory / totalMemory <= freeMemoryPercent)
+            {
+               //log.warn("Less than " + freeMemoryPercent + "% of total available memory free");
+               low = true;
+            }
+            else
+            {
+               low = false;
+            }
+             
+         }
+      }
+   }
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/postoffice/BindRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/BindRequest.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/BindRequest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,80 @@
+/*
+ * 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.impl.postoffice;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+
+/**
+ * A BindRequest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 2421 $</tt>
+ *
+ * $Id: BindRequest.java 2421 2007-02-25 00:06:06Z timfox $
+ *
+ */
+class BindRequest extends ClusterRequest
+{
+   private MappingInfo mappingInfo; 
+   
+   private boolean allNodes;
+   
+   BindRequest()
+   {      
+   }
+   
+   BindRequest(MappingInfo bindingInfo, boolean allNodes)
+   {
+      this.mappingInfo = bindingInfo;
+      
+      this.allNodes = allNodes;
+   }
+
+   Object execute(RequestTarget office) throws Exception
+   {
+      office.addBindingFromCluster(mappingInfo, allNodes);
+      
+      return null;
+   }
+   
+   byte getType()
+   {
+      return ClusterRequest.BIND_REQUEST;
+   }
+
+   public void read(DataInputStream in) throws Exception
+   {
+      mappingInfo = new MappingInfo();
+      
+      mappingInfo.read(in);
+      
+      allNodes = in.readBoolean();
+   }
+
+   public void write(DataOutputStream out) throws Exception
+   {
+      mappingInfo.write(out);
+      
+      out.writeBoolean(allNodes);
+   }
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/postoffice/ClusterRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/ClusterRequest.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/ClusterRequest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,123 @@
+/*
+ * 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.impl.postoffice;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+
+import org.jboss.messaging.util.Streamable;
+
+/**
+ * 
+ * A ClusterRequest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1917 $</tt>
+ *
+ * $Id: ClusterRequest.java 1917 2007-01-08 20:26:12Z clebert.suconic at jboss.com $
+ *
+ */
+abstract class ClusterRequest implements Streamable
+{    
+	public static final int JOIN_CLUSTER_REQUEST = 1;
+	
+	public static final int LEAVE_CLUSTER_REQUEST = 2;
+		
+	public static final int BIND_REQUEST = 3;
+	
+	public static final int UNBIND_REQUEST = 4;
+		
+	public static final int MESSAGE_REQUEST = 5;
+	
+	public static final int PUT_REPLICANT_REQUEST = 6;
+	
+	public static final int REMOVE_REPLICANT_REQUEST = 7;
+		
+	
+   /*
+    * Factory method
+    */
+   static ClusterRequest createFromStream(DataInputStream dais) throws Exception
+   {
+      byte type = dais.readByte();
+       
+      ClusterRequest request = null;
+      
+      switch (type)
+      {
+	      case MESSAGE_REQUEST:
+	      {
+	         request = new MessageRequest();
+	         break;
+	      }      
+         case BIND_REQUEST:
+         {
+            request =  new BindRequest();
+            break;
+         }
+         case UNBIND_REQUEST:
+         {
+            request = new UnbindRequest();
+            break;
+         }
+         case JOIN_CLUSTER_REQUEST:
+         {
+         	request = new JoinClusterRequest();
+         	break;
+         }
+         case LEAVE_CLUSTER_REQUEST:
+         {
+            request = new LeaveClusterRequest();
+            break;
+         }
+         case PUT_REPLICANT_REQUEST:
+         {
+            request = new PutReplicantRequest();
+            break;
+         }
+         case REMOVE_REPLICANT_REQUEST:
+         {
+            request = new RemoveReplicantRequest();
+            break;
+         }
+         default:
+         {
+            throw new IllegalArgumentException("Invalid type: " + type);
+         }
+      }
+      
+      request.read(dais);
+      
+      return request;
+   }
+   
+   public static void writeToStream(DataOutputStream daos, ClusterRequest request) throws Exception
+   {
+      daos.writeByte(request.getType());
+      
+      request.write(daos);
+   }
+   
+   abstract Object execute(RequestTarget office) throws Throwable;
+   
+   abstract byte getType();
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/postoffice/DefaultFailoverMapper.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/DefaultFailoverMapper.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/DefaultFailoverMapper.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,78 @@
+/*
+ * 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.impl.postoffice;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.messaging.core.contract.FailoverMapper;
+
+
+/**
+ * A DefaultFailoverMapper
+ * 
+ * Generates the mapping by looking to the element to the right and wrapping around to the first
+ * element in the list
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 2681 $</tt>
+ *
+ * $Id: DefaultFailoverMapper.java 2681 2007-05-15 00:09:10Z timfox $
+ *
+ */
+public class DefaultFailoverMapper implements FailoverMapper
+{
+   /**
+    * Generate a mapping given a set of nodes - nodes will be sorted by the method.
+    *
+    * @see org.jboss.messaging.core.contract.FailoverMapper#generateMapping(java.util.Set)
+    */
+   public Map generateMapping(Set nodes)
+   {
+      Integer[] nodesArr = (Integer[])nodes.toArray(new Integer[nodes.size()]);
+      
+      // First sort them so every node has a consistent view
+      Arrays.sort(nodesArr);
+      
+      int s = nodes.size();
+      
+      // There is no need for the map to be linked
+      Map failoverNodes = new HashMap(s);
+      
+      for (int i = 0; i < s; i++)
+      {
+         int j = i + 1;
+         
+         if (j == s)
+         {
+            j = 0;
+         }
+         
+         failoverNodes.put(nodesArr[i], nodesArr[j]);
+      }
+
+      return failoverNodes;
+   }
+
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/postoffice/GroupListener.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/GroupListener.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/GroupListener.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.impl.postoffice;
+
+import org.jgroups.Address;
+
+/**
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: $</tt>19 Jun 2007
+ *
+ * $Id: $
+ *
+ */
+interface GroupListener
+{
+	void nodeLeft(Address address) throws Throwable;
+	
+	void nodeJoined(Address address) throws Exception;
+	
+	byte[] getState() throws Exception;
+	
+	void setState(byte[] state) throws Exception;
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/postoffice/GroupMember.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/GroupMember.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/GroupMember.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,511 @@
+/*
+ * 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.impl.postoffice;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.util.Iterator;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.contract.JChannelFactory;
+import org.jgroups.Address;
+import org.jgroups.Channel;
+import org.jgroups.MembershipListener;
+import org.jgroups.Message;
+import org.jgroups.MessageListener;
+import org.jgroups.Receiver;
+import org.jgroups.View;
+import org.jgroups.blocks.GroupRequest;
+import org.jgroups.blocks.MessageDispatcher;
+import org.jgroups.blocks.RequestHandler;
+
+import EDU.oswego.cs.dl.util.concurrent.LinkedQueue;
+import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
+
+/**
+ * 
+ * This class handles the interface with JGroups
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: $</tt>14 Jun 2007
+ *
+ * $Id: $
+ *
+ */
+public class GroupMember
+{
+   private static final Logger log = Logger.getLogger(GroupMember.class);
+   
+	private boolean trace = log.isTraceEnabled();
+	
+   private String groupName;
+
+   private long stateTimeout;
+
+   private long castTimeout;
+   
+   private JChannelFactory jChannelFactory;
+
+   private Channel syncChannel;
+
+   private Channel asyncChannel;
+
+   private RequestTarget requestTarget;
+   
+   private GroupListener groupListener;
+   
+   private MessageDispatcher dispatcher;
+   
+   private volatile boolean stopping;
+   
+   private View currentView;
+   
+   private QueuedExecutor viewExecutor;
+   
+   private Object setStateLock = new Object();
+
+   private boolean stateSet;   
+   
+   public GroupMember(String groupName, long stateTimeout, long castTimeout,
+   		             JChannelFactory jChannelFactory, RequestTarget requestTarget,
+   		             GroupListener groupListener)
+   {
+   	this.groupName = groupName;
+   	
+   	this.stateTimeout = stateTimeout;
+   	
+   	this.castTimeout = castTimeout;
+   	
+   	this.jChannelFactory = jChannelFactory;
+   	
+   	this.requestTarget = requestTarget;
+   	
+   	this.groupListener = groupListener;
+   	
+   	this.viewExecutor = new QueuedExecutor(new LinkedQueue());
+   }
+     
+   public void start() throws Exception
+   {
+   	this.syncChannel = jChannelFactory.createSyncChannel();
+   	
+      this.asyncChannel = jChannelFactory.createASyncChannel();
+
+      // We don't want to receive local messages on any of the channels
+      syncChannel.setOpt(Channel.LOCAL, Boolean.FALSE);
+
+      asyncChannel.setOpt(Channel.LOCAL, Boolean.FALSE);
+      
+      MessageListener messageListener = new ControlMessageListener();
+      
+      MembershipListener membershipListener = new ControlMembershipListener();
+      
+      RequestHandler requestHandler = new PostOfficeRequestHandler();
+      
+      dispatcher = new MessageDispatcher(syncChannel, messageListener, membershipListener, requestHandler, true);
+      
+      Receiver dataReceiver = new DataReceiver();
+      
+      asyncChannel.setReceiver(dataReceiver);
+
+      syncChannel.connect(groupName);
+      
+      asyncChannel.connect(groupName);
+   }
+      
+   public void stop()
+   {
+   	//FIXME - we should use a ReadWriteLock here
+   	
+   	stopping = true;
+   	
+   	try
+   	{
+   		Thread.sleep(500);
+   	}
+   	catch (Exception ignore)
+   	{   		
+   	}
+   		   	
+   	syncChannel.close();
+   	
+   	asyncChannel.close();
+   }
+   
+   public Address getSyncAddress()
+   {
+   	return syncChannel.getLocalAddress();
+   }
+   
+   public Address getAsyncAddress()
+   {
+   	return asyncChannel.getLocalAddress();
+   }
+   
+   public void multicastRequest(ClusterRequest request) throws Exception
+   {
+   	if (!stopping)
+   	{   		
+	   	if (trace) { log.trace(this + " multicasting " + request + " to group"); }
+	
+	      byte[] bytes = writeRequest(request);
+	      
+	      asyncChannel.send(new Message(null, null, bytes));
+   	}
+   }
+   
+   public void unicastRequest(ClusterRequest request, Address address) throws Exception
+   {
+   	if (!stopping)
+   	{
+	   	if (trace) { log.trace(this + " unicasting " + request + " to address " + address); }
+	
+	      byte[] bytes = writeRequest(request);
+	      
+	      asyncChannel.send(new Message(address, null, bytes));
+   	}
+   }
+   
+   public void sendSyncRequest(ClusterRequest request) throws Exception
+   {
+   	if (!stopping)
+   	{
+	   	if (trace) { log.trace(this + " Sending sync request " + request); }
+	   	
+	   	Message message = new Message(null, null, writeRequest(request));
+	
+	      dispatcher.castMessage(null, message, GroupRequest.GET_ALL, castTimeout);
+   	}
+   }
+      
+   public boolean getState() throws Exception
+   {
+   	if (syncChannel.getState(null, stateTimeout))
+   	{
+   		//We are not the first member of the group, so let's wait for state to be got and processed
+   		
+   		synchronized (setStateLock)
+      	{ 
+   			long timeRemaining = stateTimeout;
+   			
+   			long start = System.currentTimeMillis();
+   			
+      		while (!stateSet && timeRemaining > 0)
+      		{
+      			setStateLock.wait(stateTimeout);
+      			
+      			if (!stateSet)
+      			{
+      				long waited = System.currentTimeMillis() - start;
+      				
+      				timeRemaining -= waited;
+      			}
+      		}
+      	}
+   		
+   		if (!stateSet)
+   		{
+   			throw new IllegalStateException("Timed out waiting for state to arrive");
+   		}
+   		
+   		return true;
+   	}
+   	else
+   	{
+   		return false;
+   	}
+   }
+   
+   
+   private ClusterRequest readRequest(byte[] bytes) throws Exception
+   {
+      ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+
+      DataInputStream dais = new DataInputStream(bais);
+
+      ClusterRequest request = ClusterRequest.createFromStream(dais);
+
+      dais.close();
+
+      return request;
+   }
+
+   
+   private byte[] writeRequest(ClusterRequest request) throws Exception
+   {
+      ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
+
+      DataOutputStream daos = new DataOutputStream(baos);
+
+      ClusterRequest.writeToStream(daos, request);
+
+      daos.flush();
+
+      return baos.toByteArray();
+   }
+   
+   /*
+    * This class is used to manage state on the control channel
+    */
+   private class ControlMessageListener implements MessageListener
+   {
+      public byte[] getState()
+      {
+         if (stopping)
+         {
+            return null;
+         }
+
+         if (trace) { log.trace(this + ".ControlMessageListener got state"); }
+         
+         try
+         {
+         	byte[] state = groupListener.getState();
+         	
+         	return state;
+         }
+         catch (Exception e)
+         {
+         	log.error("Failed to get state", e);
+         	
+         	return null;
+         }
+      }
+
+      public void receive(Message message)
+      {
+         if (stopping)
+         {
+            return;
+         }
+      }
+
+      public void setState(byte[] bytes)
+      {
+         if (stopping)
+         {
+            return;
+         }
+
+         synchronized (setStateLock)
+         {
+         	try
+         	{
+         		groupListener.setState(bytes);
+         	}
+         	catch (Exception e)
+         	{
+         		log.error("Failed to set state", e);
+         	}
+         	
+            stateSet = true;
+            
+            setStateLock.notify();
+         }
+      }
+   }
+
+   /*
+    * We use this class so we notice when members leave the group
+    */
+   private class ControlMembershipListener implements MembershipListener
+   {
+      public void block()
+      {
+         // NOOP
+      }
+
+      public void suspect(Address address)
+      {
+         // NOOP
+      }
+
+      public void viewAccepted(View newView)
+      {
+         if (stopping)
+         {
+            return;
+         }
+
+         try
+         {
+            // We queue up changes and execute them asynchronously.
+            // This is because JGroups will not let us do stuff like send synch messages using the
+            // same thread that delivered the view change and this is what we need to do in
+            // failover, for example.
+
+            viewExecutor.execute(new HandleViewAcceptedRunnable(newView));
+         }
+         catch (InterruptedException e)
+         {
+            log.warn("Caught InterruptedException", e);
+         }
+      }
+
+      public byte[] getState()
+      {
+         // NOOP
+         return null;
+      }
+   }
+   
+   /*
+    * This class is used to listen for messages on the async channel
+    */
+   private class DataReceiver implements Receiver
+   {
+      public void block()
+      {
+         //NOOP
+      }
+
+      public void suspect(Address address)
+      {
+         //NOOP
+      }
+
+      public void viewAccepted(View view)
+      {
+         //NOOP
+      }
+
+      public byte[] getState()
+      {
+         //NOOP
+         return null;
+      }
+
+      public void receive(Message message)
+      {
+         if (trace) { log.trace(this + " received " + message + " on the ASYNC channel"); }
+
+         try
+         {
+            byte[] bytes = message.getBuffer();
+
+            ClusterRequest request = readRequest(bytes);
+            request.execute(requestTarget);
+         }
+         catch (Throwable e)
+         {
+            log.error("Caught Exception in Receiver", e);
+            IllegalStateException e2 = new IllegalStateException(e.getMessage());
+            e2.setStackTrace(e.getStackTrace());
+            throw e2;
+         }
+      }
+
+      public void setState(byte[] bytes)
+      {
+         //NOOP
+      }
+   }
+
+   /*
+    * This class is used to handle synchronous requests
+    */
+   private class PostOfficeRequestHandler implements RequestHandler
+   {
+      public Object handle(Message message)
+      {
+         if (stopping)
+         {
+            return null;
+         }
+
+         if (trace) { log.trace(this + ".RequestHandler received " + message + " on the SYNC channel"); }
+
+         try
+         {
+            byte[] bytes = message.getBuffer();
+
+            ClusterRequest request = readRequest(bytes);
+
+            return request.execute(requestTarget);
+         }
+         catch (Throwable e)
+         {
+            log.error("Caught Exception in RequestHandler", e);
+            IllegalStateException e2 = new IllegalStateException(e.getMessage());
+            e2.setStackTrace(e.getStackTrace());
+            throw e2;
+         }
+      }
+   }
+   
+   private class HandleViewAcceptedRunnable implements Runnable
+   {
+      private View newView;
+
+      HandleViewAcceptedRunnable(View newView)
+      {
+         this.newView = newView;
+      }
+
+      public void run()
+      {
+         log.info(this  + " got new view " + newView);
+
+         // JGroups will make sure this method is never called by more than one thread concurrently
+
+         View oldView = currentView;
+         currentView = newView;
+
+         try
+         {
+            // Act on membership change, on both cases when an old member left or a new member joined
+
+            if (oldView != null)
+            {
+               for (Iterator i = oldView.getMembers().iterator(); i.hasNext(); )
+               {
+                  Address address = (Address)i.next();
+                  if (!newView.containsMember(address))
+                  {
+                     // this is where the failover happens, if necessary
+                     groupListener.nodeLeft(address);
+                  }
+               }
+            }
+
+            for (Iterator i = newView.getMembers().iterator(); i.hasNext(); )
+            {
+               Address address = (Address)i.next();
+               if (oldView == null || !oldView.containsMember(address))
+               {
+                  groupListener.nodeJoined(address);
+               }
+            }
+         }
+         catch (Throwable e)
+         {
+            log.error("Caught Exception in MembershipListener", e);
+            IllegalStateException e2 = new IllegalStateException(e.getMessage());
+            e2.setStackTrace(e.getStackTrace());
+            throw e2;
+         }
+      }
+   }
+
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/postoffice/LeaveClusterRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/LeaveClusterRequest.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/LeaveClusterRequest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,79 @@
+package org.jboss.messaging.core.impl.postoffice;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+
+/**
+ * A LeaveClusterRequest
+ *
+ * @author <a href="mailto:clebert.suconic at jboss.org">Clebert Suconic</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1917 $</tt>
+ *
+ * $Id: LeaveClusterRequest.java 1917 2007-01-08 20:26:12Z clebert.suconic at jboss.com $
+ */
+class LeaveClusterRequest extends ClusterRequest
+{
+   // Constants ------------------------------------------------------------------------------------
+
+   // Static ---------------------------------------------------------------------------------------
+
+   // Attributes -----------------------------------------------------------------------------------
+
+   private int nodeId;
+
+   // Constructors ---------------------------------------------------------------------------------
+
+   LeaveClusterRequest(int nodeId)
+   {
+      this.nodeId=nodeId;
+   }
+
+   /**
+    * This constructor only exist because it's an Streamable requirement.
+    * @see ClusterRequest#createFromStream(java.io.DataInputStream)
+    */
+   LeaveClusterRequest()
+   {
+   }
+
+   // Streamable implementation --------------------------------------------------------------------
+
+   public void write(DataOutputStream out) throws Exception
+   {
+      out.writeInt(nodeId);
+   }
+
+   public void read(DataInputStream in) throws Exception
+   {
+      nodeId = in.readInt();
+   }
+
+   // Public ---------------------------------------------------------------------------------------
+
+   public String toString()
+   {
+      return "LeaveClusterRequest[NID="  + nodeId + "]";
+   }
+
+   // Package protected ----------------------------------------------------------------------------
+
+   Object execute(RequestTarget office) throws Throwable
+   {
+      office.handleNodeLeft(nodeId);
+
+      return null;
+   }
+
+   byte getType()
+   {
+      return ClusterRequest.LEAVE_CLUSTER_REQUEST;
+   }
+
+   // Protected ------------------------------------------------------------------------------------
+
+   // Private --------------------------------------------------------------------------------------
+
+   // Inner classes --------------------------------------------------------------------------------
+
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/postoffice/MappingInfo.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/MappingInfo.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/MappingInfo.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,224 @@
+/*
+ * 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.impl.postoffice;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+
+import org.jboss.messaging.util.StreamUtils;
+import org.jboss.messaging.util.Streamable;
+
+/**
+ * 
+ * A MappingInfo
+ *
+ * @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: 2421 $</tt>
+ *
+ * $Id: DefaultBinding.java 2421 2007-02-25 00:06:06Z timfox $
+ *
+ */
+class MappingInfo implements Streamable
+{
+	private int nodeId;   
+   
+   private String conditionText;   
+   
+   private String filterString; 
+   
+   private long channelId;   
+   
+   private boolean recoverable;
+   
+   private int maxSize;
+   
+   private String queueName;
+   
+   private boolean clustered;
+   
+   private int fullSize;
+   
+   //We need the following attributes too when binding on ALL nodes of the cluster
+   private int pageSize;
+   
+   private int downCacheSize;
+   
+   private boolean preserveOrdering;
+   
+   MappingInfo()
+   {      
+   }
+   
+   MappingInfo(int nodeId, String queueName, String conditionText, String filterString,
+               long channelId, boolean recoverable, boolean clustered)
+   {
+      this.nodeId = nodeId;
+      
+      this.queueName = queueName;
+      
+      this.conditionText = conditionText;
+      
+      this.filterString = filterString;
+      
+      this.channelId = channelId;
+      
+      this.recoverable = recoverable;
+        
+      this.clustered = clustered;
+   }   
+   
+   MappingInfo(int nodeId, String queueName, String conditionText, String filterString,
+   		      long channelId, boolean recoverable, boolean clustered, int fullSize, int pageSize, int downCacheSize,
+   		      int maxSize, boolean preserveOrdering)
+   {
+   	this (nodeId, queueName, conditionText, filterString, channelId, recoverable, clustered);
+   	
+   	this.fullSize = fullSize;
+   	
+   	this.pageSize = pageSize;
+   	
+   	this.downCacheSize = downCacheSize;
+   	
+   	this.maxSize = maxSize;
+   	
+   	this.preserveOrdering = preserveOrdering;
+   }   
+	
+	// Streamable implementation ---------------------------------------------------------------------
+
+   public void read(DataInputStream in) throws Exception
+   {
+      nodeId = in.readInt();
+      
+      queueName = in.readUTF();
+      
+      conditionText = in.readUTF();
+      
+      filterString = (String)StreamUtils.readObject(in, false);   
+      
+      channelId = in.readLong();
+      
+      recoverable = in.readBoolean();
+      
+      clustered = in.readBoolean();
+      
+      fullSize = in.readInt();
+      
+      pageSize = in.readInt();
+      
+      downCacheSize = in.readInt();
+      
+      maxSize = in.readInt();
+      
+      preserveOrdering = in.readBoolean();
+   }
+
+   public void write(DataOutputStream out) throws Exception
+   {
+      out.writeInt(nodeId);
+      
+      out.writeUTF(queueName);
+      
+      out.writeUTF(conditionText);
+      
+      StreamUtils.writeObject(out, filterString, false, false);
+      
+      out.writeLong(channelId);
+      
+      out.writeBoolean(recoverable);
+      
+      out.writeBoolean(clustered);
+      
+      out.writeInt(fullSize);
+      
+      out.writeInt(pageSize);
+      
+      out.writeInt(downCacheSize);
+      
+      out.writeInt(maxSize);
+      
+      out.writeBoolean(preserveOrdering);
+   }
+   
+   int getNodeId()
+   {
+      return nodeId;
+   }
+   
+   String getQueueName()
+   {
+   	return queueName;
+   }
+   
+   long getChannelId()
+   {
+      return channelId;
+   }
+
+   String getConditionText()
+   {
+      return conditionText;
+   }
+
+   boolean isRecoverable()
+   {
+      return recoverable;
+   }
+
+   String getFilterString()
+   {
+      return filterString;
+   }
+   
+   boolean isClustered()
+   {
+   	return clustered;
+   }
+
+   int getFullSize()
+   {
+   	return fullSize;
+   }
+   
+   int getPageSize()
+   {
+   	return pageSize;   	
+   }
+   
+   int getDownCacheSize()
+   {
+   	return downCacheSize;
+   }
+   
+   boolean isPreserveOrdering()
+   {
+   	return preserveOrdering;
+   }
+   
+   int getMaxSize()
+   {
+   	return maxSize;
+   }
+
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/postoffice/MessageHolder.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/MessageHolder.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/MessageHolder.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,99 @@
+/*
+ * 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.impl.postoffice;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.util.Map;
+
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.impl.message.MessageFactory;
+import org.jboss.messaging.util.StreamUtils;
+import org.jboss.messaging.util.Streamable;
+
+/**
+ * A MessageHolder
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 2202 $</tt>
+ *
+ * $Id: MessageHolder.java 2202 2007-02-08 10:50:26Z timfox $
+ *
+ */
+class MessageHolder implements Streamable
+{
+   private String routingKeyText;
+   
+   private Message message;
+   
+   private Map queueNameToNodeIdMap;
+   
+   public MessageHolder()
+   {      
+   }
+   
+   MessageHolder(String routingKeyText, Message message, Map queueNameToNodeIdMap)
+   {
+      this.routingKeyText = routingKeyText;
+      
+      this.message = message;
+      
+      this.queueNameToNodeIdMap = queueNameToNodeIdMap;
+   }
+   
+   String getRoutingKey()
+   {
+      return routingKeyText;
+   }
+   
+   Message getMessage()
+   {
+      return message;
+   }
+   
+   Map getQueueNameToNodeIdMap()
+   {
+      return queueNameToNodeIdMap;
+   }
+
+   public void read(DataInputStream in) throws Exception
+   {
+      routingKeyText = in.readUTF();
+      
+      byte type = in.readByte();
+        
+      message = MessageFactory.createMessage(type);
+      message.read(in);
+      
+      queueNameToNodeIdMap = (Map)StreamUtils.readObject(in, false);      
+   }
+
+   public void write(DataOutputStream out) throws Exception
+   {
+      out.writeUTF(routingKeyText);
+      
+      out.writeByte(message.getType());      
+      message.write(out);
+
+      StreamUtils.writeObject(out, queueNameToNodeIdMap, true, false);
+   }
+}     

Added: trunk/src/main/org/jboss/messaging/core/impl/postoffice/MessageRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/MessageRequest.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/MessageRequest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,91 @@
+/*
+ * 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.impl.postoffice;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.util.Map;
+
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.impl.message.MessageFactory;
+import org.jboss.messaging.util.StreamUtils;
+
+/**
+ * A MessageRequest
+ * 
+ * Used when sending a single message non reliably across the group
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 2202 $</tt>
+ *
+ * $Id: MessageRequest.java 2202 2007-02-08 10:50:26Z timfox $
+ *
+ */
+class MessageRequest extends ClusterRequest
+{
+   private String routingConditionText;   
+   
+   private Message message;
+   
+   MessageRequest()
+   {      
+   }
+   
+   MessageRequest(String routingConditionText, Message message)
+   {
+      this.routingConditionText = routingConditionText;
+      
+      this.message = message;
+   }
+   
+   Object execute(RequestTarget office) throws Exception
+   {
+      office.routeFromCluster(message, routingConditionText);      
+      
+      return null;
+   }  
+   
+   byte getType()
+   {
+      return ClusterRequest.MESSAGE_REQUEST;
+   }
+   
+   public void read(DataInputStream in) throws Exception
+   {
+      routingConditionText = in.readUTF();
+      
+      byte type = in.readByte();
+      
+      message = MessageFactory.createMessage(type);
+      
+      message.read(in);        
+   }
+
+   public void write(DataOutputStream out) throws Exception
+   {
+      out.writeUTF(routingConditionText);
+      
+      out.writeByte(message.getType());      
+      
+      message.write(out);
+   }
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/postoffice/MessagingPostOffice.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/MessagingPostOffice.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/MessagingPostOffice.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,2132 @@
+/*
+ * 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.impl.postoffice;
+
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanNotificationInfo;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.sql.DataSource;
+import javax.transaction.TransactionManager;
+
+import org.jboss.jms.server.JMSCondition;
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.contract.Binding;
+import org.jboss.messaging.core.contract.ClusterNotification;
+import org.jboss.messaging.core.contract.ClusterNotifier;
+import org.jboss.messaging.core.contract.Condition;
+import org.jboss.messaging.core.contract.ConditionFactory;
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.FailoverMapper;
+import org.jboss.messaging.core.contract.Filter;
+import org.jboss.messaging.core.contract.FilterFactory;
+import org.jboss.messaging.core.contract.JChannelFactory;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.PersistenceManager;
+import org.jboss.messaging.core.contract.PostOffice;
+import org.jboss.messaging.core.contract.Queue;
+import org.jboss.messaging.core.contract.Replicator;
+import org.jboss.messaging.core.impl.IDManager;
+import org.jboss.messaging.core.impl.JDBCSupport;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.core.impl.tx.TransactionRepository;
+import org.jboss.messaging.util.StreamUtils;
+import org.jgroups.Address;
+
+import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
+import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
+import EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock;
+
+/**
+ * @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:clebert.suconic at jboss.com">Clebert Suconic</a>
+ * @version <tt>$Revision: 2782 $</tt>
+ *
+ * $Id: DefaultClusteredPostOffice.java 2782 2007-06-14 12:16:17Z timfox $
+ *
+ */
+public class MessagingPostOffice extends JDBCSupport
+   implements PostOffice, RequestTarget, GroupListener, Replicator
+{
+   // Constants ------------------------------------------------------------------------------------
+
+   private static final Logger log = Logger.getLogger(MessagingPostOffice.class);
+
+   //This are only used in testing
+   
+   public static final String VIEW_CHANGED_NOTIFICATION = "VIEW_CHANGED";
+   
+   public static final String FAILOVER_COMPLETED_NOTIFICATION = "FAILOVER_COMPLETED";
+   
+   //End only used in testing
+
+   // Static ---------------------------------------------------------------------------------------
+
+   /**
+    * @param map - Map<Integer(nodeID)-Integer(failoverNodeID)>
+    */
+   public static String dumpFailoverMap(Map map)
+   {
+      StringBuffer sb = new StringBuffer("\n");
+
+      for(Iterator i = map.entrySet().iterator(); i.hasNext(); )
+      {
+         Map.Entry entry = (Map.Entry)i.next();
+         Integer primary = (Integer)entry.getKey();
+         Integer secondary = (Integer)entry.getValue();
+         sb.append("             ").append(primary).append("->").append(secondary).append("\n");
+      }
+      return sb.toString();
+   }
+
+   /**
+    * @param map - Map<Integer(nodeID)-PostOfficeAddressInfo>
+    */
+   public static String dumpClusterMap(Map map)
+   {
+      StringBuffer sb = new StringBuffer("\n");
+
+      for(Iterator i = map.entrySet().iterator(); i.hasNext(); )
+      {
+         Map.Entry entry = (Map.Entry)i.next();
+         Integer nodeID = (Integer)entry.getKey();
+         PostOfficeAddressInfo info = (PostOfficeAddressInfo)entry.getValue();
+         sb.append("             ").append(nodeID).append("->").append(info).append("\n");
+      }
+      return sb.toString();
+   }
+
+   // Attributes -----------------------------------------------------------------------------------
+
+   // End of failure testing attributes
+
+   private boolean trace = log.isTraceEnabled();
+      
+   private MessageStore ms;
+   
+   private PersistenceManager pm;
+   
+   private TransactionRepository tr;
+   
+   private FilterFactory filterFactory;
+   
+   private ConditionFactory conditionFactory;
+   
+   private int thisNodeID;
+
+   // Map <Condition, List <Queue>> - for ALL nodes
+   private Map mappings;
+   
+   // Map <queue name, Binding> - only for the current node
+   private Map nameMap;
+   
+   // Map <channel id, Binding> - only for the current node
+   private Map channelIDMap;
+
+   // this lock protects the bindings
+   private ReadWriteLock bindingsLock;
+   
+   private String officeName;
+   
+   private boolean clustered;
+   
+   private volatile boolean started;
+   
+   //FIXME using a stopping flag is not a good approach and introduces a race condition
+   //http://jira.jboss.org/jira/browse/JBMESSAGING-819
+   //the code can check stopping and find it to be false, then the service can stop, setting stopping to true
+   //then actually stopping the post office, then the same thread that checked stopping continues and performs
+   //its action only to find the service stopped
+   //Should use a read-write lock instead
+   //One way to minimise the chance of the race happening is to sleep for a little while after setting stopping to true
+   //before actually stopping the service (see below)
+   private volatile boolean stopping;
+
+   private GroupMember groupMember;
+
+   private Map replicatedData;
+
+   // Map <Integer(nodeID)->Integer(failoverNodeID)>
+   private Map failoverMap;
+
+   private Set leftSet;
+
+   private FailoverMapper failoverMapper;
+
+   private NotificationBroadcasterSupport nbSupport;
+   
+   private IDManager channelIDManager;
+   
+   private ClusterNotifier clusterNotifier;
+   
+   // Map <node id, PostOfficeAddressInfo>
+   private Map nodeIDAddressMap;
+
+   // Constructors ---------------------------------------------------------------------------------
+
+   /*
+    * Constructor for a non clustered post office
+    */
+   public MessagingPostOffice(DataSource ds,
+                              TransactionManager tm,
+                              Properties sqlProperties,
+                              boolean createTablesOnStartup,
+                              int nodeId,
+                              String officeName,
+                              MessageStore ms,
+                              PersistenceManager pm,
+                              TransactionRepository tr,
+                              FilterFactory filterFactory,
+                              ConditionFactory conditionFactory,
+                              IDManager channelIDManager,
+                              ClusterNotifier clusterNotifier)
+      throws Exception
+   {
+   	super (ds, tm, sqlProperties, createTablesOnStartup);
+
+      this.thisNodeID = nodeId;
+      
+      this.ms = ms;
+      
+      this.pm = pm;
+      
+      this.tr = tr;
+      
+      this.filterFactory = filterFactory;
+      
+      this.conditionFactory = conditionFactory;
+      
+      this.officeName = officeName;
+      
+      this.clustered = false;
+      
+      this.channelIDManager = channelIDManager;
+      
+      this.clusterNotifier = clusterNotifier;
+
+      bindingsLock = new ReentrantWriterPreferenceReadWriteLock();
+      
+      mappings = new HashMap();
+      
+      nameMap = new HashMap();
+      
+      channelIDMap = new HashMap(); 
+      
+      nodeIDAddressMap = new ConcurrentHashMap();           
+   }
+   
+   /*
+    * Constructor for a clustered post office
+    */
+   public MessagingPostOffice(DataSource ds,
+                              TransactionManager tm,
+                              Properties sqlProperties,
+                              boolean createTablesOnStartup,
+                              int nodeId,
+                              String officeName,
+                              MessageStore ms,
+                              PersistenceManager pm,
+                              TransactionRepository tr,
+                              FilterFactory filterFactory,
+                              ConditionFactory conditionFactory,
+                              IDManager channelIDManager,
+                              ClusterNotifier clusterNotifier,
+                              String groupName,
+                              JChannelFactory jChannelFactory,
+                              long stateTimeout, long castTimeout,
+                              FailoverMapper failoverMapper)
+      throws Exception
+   {
+   	this(ds, tm, sqlProperties, createTablesOnStartup, nodeId, officeName, ms, pm, tr,
+   		  filterFactory, conditionFactory, channelIDManager, clusterNotifier);
+     
+      this.failoverMapper = failoverMapper;
+      
+      this.clustered = true;
+
+      replicatedData = new HashMap();
+
+      failoverMap = new LinkedHashMap();
+
+      leftSet = new HashSet();
+
+      groupMember = new GroupMember(groupName, stateTimeout, castTimeout, jChannelFactory, this, this);
+      
+      nbSupport = new NotificationBroadcasterSupport();           
+   }
+
+   // MessagingComponent overrides -----------------------------------------------------------------
+
+   public synchronized void start() throws Exception
+   {
+      if (started)
+      {
+         log.warn("Attempt to start() but " + this + " is already started");
+      }
+
+      if (trace) { log.trace(this + " starting"); }
+      
+      super.start();
+
+      if (clustered)
+      {
+	      groupMember.start();
+
+      	//First get the shared state from the cluster if appropriate
+      	
+      	if (!groupMember.getState())
+      	{
+      		if (trace) { log.trace(this + " is the first member of group"); }
+      	}
+      	else
+      	{
+      		if (trace) { log.trace(this + " is not the first member of group"); }
+      	}
+
+	      //Sanity check - we check there aren't any other nodes already in the cluster with the same node id
+	      if (knowAboutNodeId(thisNodeID))
+	      {
+	      	throw new IllegalArgumentException("Cannot start post office since there is already a post office in the " +
+	      			"cluster with the same node id (" + this.thisNodeID + "). " +
+	      			"Are you sure you have given each node a unique node id during installation?");
+	      }
+	
+	      PostOfficeAddressInfo info = new PostOfficeAddressInfo(groupMember.getSyncAddress(), groupMember.getAsyncAddress());
+	      
+	      nodeIDAddressMap.put(new Integer(thisNodeID), info);	     
+	      
+	      //calculate the failover map
+	      calculateFailoverMap();
+	      
+	      syncSendRequest(new JoinClusterRequest(thisNodeID, info));
+      }
+      
+      //Now load the bindings for this node
+      
+      loadBindingsFromStorage();  
+      
+      started = true;
+      
+      log.debug(this + " started");
+   }
+
+   public synchronized void stop() throws Exception
+   {
+      if (trace) { log.trace(this + " stopping"); }
+
+      if (!started)
+      {
+         log.warn("Attempt to stop() but " + this + " is not started");
+         return;
+      }
+      
+      super.stop();      
+      
+      if (clustered)
+      {	      
+      	try
+      	{
+		      //Need to send this *before* stopping
+		      syncSendRequest(new LeaveClusterRequest(thisNodeID));
+		
+		      stopping = true;
+		      
+		      //FIXME http://jira.jboss.org/jira/browse/JBMESSAGING-819 this is a temporary kludge for now
+		      Thread.sleep(999);
+	      
+		      groupMember.stop();
+      	}
+      	catch (Throwable t)
+      	{
+      		if (trace) { log.trace("Failure in stopping post office", t); }
+      	}
+      }
+      
+      started = false;
+
+      log.debug(this + " stopped");
+   }
+
+   // NotificationBroadcaster implementation -------------------------------------------------------
+
+   public void addNotificationListener(NotificationListener listener,
+                                       NotificationFilter filter,
+                                       Object object) throws IllegalArgumentException
+   {
+      nbSupport.addNotificationListener(listener, filter, object);
+   }
+
+   public void removeNotificationListener(NotificationListener listener)
+      throws ListenerNotFoundException
+   {
+      nbSupport.removeNotificationListener(listener);
+   }
+
+   public MBeanNotificationInfo[] getNotificationInfo()
+   {
+      return new MBeanNotificationInfo[0];
+   }
+   
+   // PostOffice implementation -------------------------------------------------------------------------
+   
+   public String getOfficeName()
+   {
+   	return officeName;
+   }
+   
+   public void addBinding(Binding binding, boolean allNodes) throws Exception
+   {
+   	if (trace) { log.trace(this.thisNodeID + " binding " + binding.queue + " with condition " + binding.condition + " all nodes " + allNodes); }
+
+   	if (binding == null)
+      {
+         throw new IllegalArgumentException("Binding is null");
+      }
+   	
+   	Condition condition = binding.condition;
+   	
+   	Queue queue = binding.queue;
+   	
+   	if (queue == null)
+      {
+         throw new IllegalArgumentException("Queue is null");
+      }
+   	
+   	if (queue.getNodeID() != thisNodeID)
+   	{
+   		throw new IllegalArgumentException("Cannot bind a queue from another node");
+   	}
+
+      if (condition == null)
+      {
+         throw new IllegalArgumentException("Condition is null");
+      }
+
+      bindingsLock.writeLock().acquire();
+
+      try
+      {
+      	addBindingInMemory(binding);
+      }
+      finally
+      {
+         bindingsLock.writeLock().release();
+      }   	
+      
+      if (queue.isRecoverable())
+      {
+         // Need to write the mapping to the database
+         insertBindingInStorage(condition, queue);
+      }
+
+      if (clustered && queue.isClustered())
+      {
+      	String filterString = queue.getFilter() == null ? null : queue.getFilter().getFilterString();      	
+      	
+      	MappingInfo info = new MappingInfo(thisNodeID, queue.getName(), condition.toText(), filterString, queue.getChannelID(),
+      			                             queue.isRecoverable(), true,
+      			                             queue.getFullSize(), queue.getPageSize(), queue.getDownCacheSize(),
+      			                             queue.getMaxSize(),
+      			                             queue.isPreserveOrdering());
+      	
+         ClusterRequest request = new BindRequest(info, allNodes);
+
+         syncSendRequest(request);         
+      }
+   }
+   
+   public void removeBinding(String queueName, boolean allNodes) throws Throwable
+   {
+      if (trace) { log.trace(this.thisNodeID + " unbind queue: " + queueName + " all nodes " + allNodes); }
+
+      if (queueName == null)
+      {
+         throw new IllegalArgumentException("Queue name is null");
+      }
+
+      bindingsLock.writeLock().acquire();
+      
+      Binding removed;
+      
+      try
+      {
+      	removed = (Binding)nameMap.get(queueName);
+      	
+         if (removed == null)
+         {
+         	throw new IllegalStateException("Cannot find queue to unbind " + queueName);
+         }
+         
+         removeBindingInMemory(removed);                  
+      }
+      finally
+      {
+         bindingsLock.writeLock().release();
+      }
+      
+      Queue queue = removed.queue;
+      
+      Condition condition = removed.condition;
+      	     	
+      if (queue.isRecoverable())
+      {
+         //Need to remove from db too
+
+         deleteBindingFromStorage(queue);
+      }
+
+      queue.removeAllReferences();
+      
+      if (clustered && queue.isClustered())
+      {
+      	String filterString = queue.getFilter() == null ? null : queue.getFilter().getFilterString();      	
+      	
+      	MappingInfo info = new MappingInfo(thisNodeID, queue.getName(), condition.toText(), filterString, queue.getChannelID(),
+      			                             queue.isRecoverable(), true);
+      	
+	      UnbindRequest request = new UnbindRequest(info, allNodes);
+	
+	      syncSendRequest(request);
+      }
+   }
+                  
+   public boolean route(MessageReference ref, Condition condition, Transaction tx) throws Exception
+   {
+      if (ref == null)
+      {
+         throw new IllegalArgumentException("Message reference is null");
+      }
+
+      if (condition == null)
+      {
+         throw new IllegalArgumentException("Condition is null");
+      }
+      
+      return routeInternal(ref, condition, tx, false);
+   }
+
+   public Collection getQueuesForCondition(Condition condition, boolean localOnly) throws Exception
+   {
+   	if (condition == null)
+   	{
+   		throw new IllegalArgumentException("Condition is null");
+   	}
+   	
+   	if (!localOnly && !clustered)
+   	{
+   		throw new IllegalArgumentException("Cannot request clustered queues on non clustered post office");
+   	}
+
+   	bindingsLock.readLock().acquire();
+
+   	try
+   	{
+   		//We should only list the bindings for the local node
+
+   		List queues = (List)mappings.get(condition);
+
+   		if (queues == null)
+   		{
+   			return Collections.EMPTY_LIST;
+   		}
+   		else
+   		{
+   			List list = new ArrayList();
+
+   			Iterator iter = queues.iterator();
+
+   			while (iter.hasNext())
+   			{
+   				Queue queue = (Queue)iter.next();
+
+   				if (!localOnly || (queue.getNodeID() == this.thisNodeID))
+   				{
+   					list.add(queue);
+   				}
+   			}
+
+   			return list;
+   		}
+   	}
+   	finally
+   	{
+   		bindingsLock.readLock().release();
+   	}
+   }
+   
+   public Binding getBindingForQueueName(String queueName) throws Exception
+   {
+   	if (queueName == null)
+   	{
+   		throw new IllegalArgumentException("Queue name is null");
+   	}
+   	
+   	bindingsLock.readLock().acquire();
+
+   	try
+   	{
+   		Binding binding = (Binding)nameMap.get(queueName);
+   		
+   		return binding;
+   	}
+   	finally
+   	{
+   		bindingsLock.readLock().release();
+   	}
+   }
+   
+   public Binding getBindingForChannelID(long channelID) throws Exception
+   {
+   	bindingsLock.readLock().acquire();
+
+   	try
+   	{
+   		Binding binding = (Binding)channelIDMap.get(new Long(channelID));
+   		
+   		return binding;
+   	}
+   	finally
+   	{
+   		bindingsLock.readLock().release();
+   	}
+   }
+              
+   public boolean isClustered()
+   {
+      return clustered;
+   }
+   
+   public Map getFailoverMap()
+   {
+   	synchronized (failoverMap)
+   	{
+	   	Map map = new HashMap(failoverMap);
+	   	
+	   	return map;
+   	}
+   }
+   
+   public Collection getAllBindingsForQueueName(String queueName) throws Exception
+   {
+   	return getBindings(queueName);
+   }
+      
+   public Collection getAllBindings() throws Exception
+   {
+   	return getBindings(null);
+   }
+   
+   public Set nodeIDView()
+   {
+   	return new HashSet(nodeIDAddressMap.keySet());
+   }
+   
+   // GroupListener implementation -------------------------------------------------------------
+
+   public void setState(byte[] bytes) throws Exception
+   {
+      if (trace) { log.trace(this + " received state from group"); }
+
+      SharedState state = new SharedState();
+
+      StreamUtils.fromBytes(state, bytes);
+
+      if (trace) { log.trace(this + " received " + state.getMappings().size() + " bindings and map " + state.getReplicatedData()); }
+
+      //No need to lock since only called when starting
+      
+      mappings.clear();
+
+      List mappings = state.getMappings();
+      
+      Iterator iter = mappings.iterator();
+
+      while (iter.hasNext())
+      {
+         MappingInfo mapping = (MappingInfo)iter.next();
+
+         Filter filter = null;
+         
+         if (mapping.getFilterString() != null)
+         {
+         	filter = filterFactory.createFilter(mapping.getFilterString());
+         }
+         
+         Queue queue = new MessagingQueue(mapping.getNodeId(), mapping.getQueueName(), mapping.getChannelId(),
+                                          mapping.isRecoverable(), filter, mapping.isClustered());
+         
+         Condition condition = conditionFactory.createCondition(mapping.getConditionText());
+         
+         addBindingInMemory(new Binding(condition, queue));
+      }
+
+      //Update the replicated data
+
+      synchronized (replicatedData)
+      {
+         replicatedData = copyReplicatedData(state.getReplicatedData());
+      }
+          
+      nodeIDAddressMap = new ConcurrentHashMap(state.getNodeIDAddressMap());      
+   }
+      
+   public byte[] getState() throws Exception
+   {
+      List list = new ArrayList();
+      
+      bindingsLock.readLock().acquire();
+      
+      try
+      {
+	      Iterator iter = mappings.entrySet().iterator();
+	      
+	      while (iter.hasNext())
+	      {
+	      	Map.Entry entry = (Map.Entry)iter.next();
+	      	
+	      	Condition condition = (Condition)entry.getKey();
+	      	
+	      	List queues = (List)entry.getValue();
+	      	
+	      	Iterator iter2 = queues.iterator();
+	      	
+	      	while (iter2.hasNext())
+	      	{
+	      		Queue queue = (Queue)iter2.next();
+	      		
+	      		//We only get the clustered queues
+	      		if (queue.isClustered())
+	      		{		      		
+		      		String filterString = queue.getFilter() == null ? null : queue.getFilter().getFilterString();
+		      		
+		      		MappingInfo mapping = new MappingInfo(queue.getNodeID(), queue.getName(), condition.toText(),
+		      				                                filterString, queue.getChannelID(), queue.isRecoverable(),
+		      				                                true);		      		
+		      		list.add(mapping);
+	      		}
+	      	}
+	      }     
+      }
+      finally
+      {
+      	bindingsLock.readLock().release();
+      }
+
+      //Need to copy
+
+      Map copy;
+
+      synchronized (replicatedData)
+      {
+         copy = copyReplicatedData(replicatedData);
+      }
+
+      SharedState state = new SharedState(list, copy, new HashMap(nodeIDAddressMap));
+
+      return StreamUtils.toBytes(state);
+   }
+   
+   /*
+    * A new node has joined the group
+    */
+   public void nodeJoined(Address address) throws Exception
+   {
+      log.debug(this + ": " + address + " joined");
+      
+      // Currently does nothing
+   }
+
+   /*
+    * A node has left the group
+    */
+   public void nodeLeft(Address address) throws Throwable
+   {
+      log.debug(this + ": " + address + " left");
+
+      Integer leftNodeID = getNodeIDForSyncAddress(address);
+
+      if (leftNodeID == null)
+      {
+         throw new IllegalStateException(this + " cannot find node ID for address " + address);
+      }
+
+      boolean crashed = !this.leaveMessageReceived(leftNodeID);
+
+      log.debug(this + ": node " + leftNodeID + " has " + (crashed ? "crashed" : "cleanly left the group"));
+      
+      if (crashed)
+      {	      
+	      // Need to evaluate this before we regenerate the failover map
+	      Integer failoverNode = (Integer)failoverMap.get(leftNodeID);
+	
+	      if (failoverNode == null)
+	      {
+	         throw new IllegalStateException(this + " cannot find failover node for node " + leftNodeID);
+	      }
+		      
+	      if (thisNodeID == failoverNode.intValue())
+	      {
+	         // The node crashed and we are the failover node so let's perform failover
+	
+	         log.info(this + ": I am the failover node for node " + leftNodeID + " that crashed");
+	
+	         performFailover(leftNodeID);
+	      }
+      }
+      
+      // Remove any replicant data and non durable bindings for the node - again we need to do
+      // this irrespective of whether we crashed. This will notify any listeners which will
+      // recalculate the connection factory delegates and failover delegates.
+
+      cleanDataForNode(leftNodeID);
+      
+      this.sendJMXNotification(VIEW_CHANGED_NOTIFICATION);
+   }
+   
+   // RequestTarget implementation ------------------------------------------------------------
+   
+   /*
+    * Called when another node adds a binding
+    */
+   public void addBindingFromCluster(MappingInfo mapping, boolean allNodes) throws Exception
+   {
+      log.debug(this + " adding binding from node " + mapping.getNodeId() + ", queue " + mapping.getQueueName() +
+                " with condition " + mapping.getConditionText() + " all nodes " + allNodes);
+      
+      //Sanity
+   	
+      if (!knowAboutNodeId(mapping.getNodeId()))
+      {
+         throw new IllegalStateException("Don't know about node id: " + mapping.getNodeId());
+      }
+      
+   	//Create a mapping corresponding to the remote queue
+   	Filter filter = null;
+      
+      if (mapping.getFilterString() != null)
+      {
+      	filter = filterFactory.createFilter(mapping.getFilterString());
+      }
+      
+      Queue queue = new MessagingQueue(mapping.getNodeId(), mapping.getQueueName(), mapping.getChannelId(),
+                                       mapping.isRecoverable(), filter, mapping.isClustered());
+      
+      Condition condition = conditionFactory.createCondition(mapping.getConditionText());
+      
+      
+      bindingsLock.writeLock().acquire();
+
+      try
+      {
+         addBindingInMemory(new Binding(condition, queue));  	
+      }
+      finally
+      {
+      	bindingsLock.writeLock().release();
+      }
+      
+      if (allNodes)
+   	{
+   		if (trace) { log.trace("allNodes is true, so also forcing a local bind"); }
+   		
+   		//Also bind locally
+
+   		long channelID = channelIDManager.getID();
+   		
+   		Queue queue2 = new MessagingQueue(thisNodeID, mapping.getQueueName(), channelID, ms, pm,
+   				                            mapping.isRecoverable(), mapping.getMaxSize(), filter,
+   				                            mapping.getFullSize(), mapping.getPageSize(), mapping.getDownCacheSize(), true,
+   				                            mapping.isPreserveOrdering());
+
+   		addBinding(new Binding(condition, queue2), false);
+   		
+   		queue2.load();
+   		
+   		queue2.activate();
+   	}
+   }
+ 
+   /*
+    * Called when another node removes a binding
+    */
+   public void removeBindingFromCluster(MappingInfo mapping, boolean allNodes) throws Throwable
+   {
+      log.debug(this + " removing binding from node " + mapping.getNodeId() + ", queue " + mapping.getQueueName() +
+                " with condition " + mapping.getConditionText());
+      // Sanity
+      if (!knowAboutNodeId(mapping.getNodeId()))
+      {
+      	throw new IllegalStateException("Don't know about node id: " + mapping.getNodeId());
+      }
+
+      Filter filter = null;
+
+      if (mapping.getFilterString() != null)
+      {
+      	filter = filterFactory.createFilter(mapping.getFilterString());
+      }
+
+      Queue queue = new MessagingQueue(mapping.getNodeId(), mapping.getQueueName(), mapping.getChannelId(),
+      		                           mapping.isRecoverable(), filter, mapping.isClustered());
+
+      Condition condition = conditionFactory.createCondition(mapping.getConditionText());
+
+
+      bindingsLock.writeLock().acquire();
+
+      try
+      {
+         removeBindingInMemory(new Binding(condition, queue));        
+      }
+      finally
+      {
+         bindingsLock.writeLock().release();
+      }
+      
+      if (allNodes)
+      {
+      	//Also unbind locally
+      	
+   		if (trace) { log.trace("allNodes is true, so also forcing a local unbind"); }
+   		         	
+   		removeBinding(mapping.getQueueName(), false);
+      }
+   }
+
+   public void handleNodeLeft(int nodeId) throws Exception
+   {
+   	//No need to remove the nodeid-address map info, this will be removed when data cleaned for node
+   	
+      synchronized (leftSet)
+      {
+         leftSet.add(new Integer(nodeId));
+      }
+      
+      //We don't update the failover map here since this doesn't get called if the node crashed
+   }
+   
+   public void handleNodeJoined(int nodeId, PostOfficeAddressInfo info) throws Exception
+   {	   	   	   	
+   	nodeIDAddressMap.put(new Integer(nodeId), info);
+   	
+   	log.info(this + " handleNodeJoined: " + nodeId + " size: " + nodeIDAddressMap.size());
+   	   
+   	calculateFailoverMap();
+      
+      log.debug("Updated failover map:\n" + dumpFailoverMap(failoverMap));   	
+      
+      // Send a notification
+      
+      ClusterNotification notification = new ClusterNotification(ClusterNotification.TYPE_NODE_JOIN, nodeId, null);
+      
+      clusterNotifier.sendNotification(notification);
+      
+      this.sendJMXNotification(VIEW_CHANGED_NOTIFICATION);
+   }
+
+   /**
+    * @param originatorNodeID - the ID of the node that initiated the modification.
+    */
+   public void putReplicantLocally(int originatorNodeID, Serializable key, Serializable replicant) throws Exception
+   {
+      Map m = null;
+      
+      synchronized (replicatedData)
+      {
+         log.debug(this + " puts replicant locally: " + key + "->" + replicant);
+
+         m = (Map)replicatedData.get(key);
+
+         if (m == null)
+         {
+            m = new LinkedHashMap();
+
+            replicatedData.put(key, m);
+         }
+
+         m.put(new Integer(originatorNodeID), replicant);
+
+         if (trace) { log.trace(this + " putReplicantLocally completed"); }
+      }
+      
+      ClusterNotification notification = new ClusterNotification(ClusterNotification.TYPE_REPLICATOR_PUT, originatorNodeID, key);
+      
+      clusterNotifier.sendNotification(notification);
+   }
+
+   /**
+    * @param originatorNodeID - the ID of the node that initiated the modification.
+    */
+   public boolean removeReplicantLocally(int originatorNodeID, Serializable key) throws Exception
+   {
+      Map m = null;
+      
+      synchronized (replicatedData)
+      {
+         if (trace) { log.trace(this + " removes " + originatorNodeID + "'s replicant locally for key " + key); }
+
+         m = (Map)replicatedData.get(key);
+
+         if (m == null)
+         {
+            return false;
+         }
+
+         Object obj = m.remove(new Integer(originatorNodeID));
+
+         if (obj == null)
+         {
+            return false;
+         }
+
+         if (m.isEmpty())
+         {
+            replicatedData.remove(key);
+         }
+      }
+      
+      ClusterNotification notification = new ClusterNotification(ClusterNotification.TYPE_REPLICATOR_REMOVE, originatorNodeID, key);
+      
+      clusterNotifier.sendNotification(notification);
+      
+      return true;
+   }
+
+   public void routeFromCluster(Message message, String routingKeyText) throws Exception
+   {
+      if (trace) { log.trace(this + " routing from cluster " + message + ", routing key " + routingKeyText); }
+
+      Condition routingKey = conditionFactory.createCondition(routingKeyText);
+
+      MessageReference ref = null;
+      
+      try
+      {
+         ref = ms.reference(message);
+         
+         routeInternal(ref, routingKey, null, true);        
+      }
+      finally
+      {
+         if (ref != null)
+         {
+            ref.releaseMemoryReference();
+         }
+      }
+   }
+
+   // Replicator implementation --------------------------------------------------------------------
+
+   public void put(Serializable key, Serializable replicant) throws Exception
+   {
+      putReplicantLocally(thisNodeID, key, replicant);
+
+      PutReplicantRequest request = new PutReplicantRequest(thisNodeID, key, replicant);
+
+      syncSendRequest(request);
+   }
+
+   public Map get(Serializable key) throws Exception
+   {
+      synchronized (replicatedData)
+      {
+         Map m = (Map)replicatedData.get(key);
+
+         return m == null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(m);
+      }
+   }
+
+   public boolean remove(Serializable key) throws Exception
+   {
+      if (removeReplicantLocally(this.thisNodeID, key))
+      {
+         RemoveReplicantRequest request = new RemoveReplicantRequest(this.thisNodeID, key);
+
+         syncSendRequest(request);
+
+         return true;
+      }
+      else
+      {
+         return false;
+      }
+   }
+
+   public FailoverMapper getFailoverMapper()
+   {
+      return failoverMapper;
+   }
+   
+   // JDBCSupport overrides ------------------------------------------------------------------------
+   
+   protected Map getDefaultDMLStatements()
+   {
+      Map map = new LinkedHashMap();
+
+      map.put("INSERT_BINDING",
+              "INSERT INTO JBM_POSTOFFICE (" +
+                 "POSTOFFICE_NAME, " +
+                 "NODE_ID, " +
+                 "QUEUE_NAME, " +
+                 "CONDITION, " +
+                 "SELECTOR, " +
+                 "CHANNEL_ID, " +
+                 "CLUSTERED) " +
+              "VALUES (?, ?, ?, ?, ?, ?, ?)");
+
+      map.put("DELETE_BINDING",
+              "DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?");
+
+      map.put("LOAD_BINDINGS",
+              "SELECT " +                
+                 "QUEUE_NAME, " +
+                 "CONDITION, " +
+                 "SELECTOR, " +
+                 "CHANNEL_ID, " +
+                 "CLUSTERED " +
+                 "FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=?");
+
+      return map;
+   }
+
+   protected Map getDefaultDDLStatements()
+   {
+      Map map = new LinkedHashMap();
+      map.put("CREATE_POSTOFFICE_TABLE",
+              "CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID INTEGER," +
+              "QUEUE_NAME VARCHAR(1023), CONDITION VARCHAR(1023), " +
+              "SELECTOR VARCHAR(1023), CHANNEL_ID BIGINT, " +
+              "CLUSTERED CHAR(1))");
+      return map;
+   }
+
+   // Public ---------------------------------------------------------------------------------------
+
+   public String printBindingInformation()
+   {
+//      StringWriter buffer = new StringWriter();
+//      PrintWriter out = new PrintWriter(buffer);
+//      out.println("Ocurrencies of nameMaps:");
+//      out.println("<table border=1>");
+//      for (Iterator mapIterator = nameMaps.entrySet().iterator();mapIterator.hasNext();)
+//      {
+//          Map.Entry entry = (Map.Entry)mapIterator.next();
+//          out.println("<tr><td colspan=3><b>Map on node " + entry.getKey() + "</b></td></tr>");
+//          Map valuesOnNode = (Map)entry.getValue();
+//
+//          out.println("<tr><td>Key</td><td>Value</td><td>Class of Value</td></tr>");
+//          for (Iterator valuesIterator=valuesOnNode.entrySet().iterator();valuesIterator.hasNext();)
+//          {
+//              Map.Entry entry2 = (Map.Entry)valuesIterator.next();
+//
+//              out.println("<tr>");
+//              out.println("<td>" + entry2.getKey() + "</td><td>" + entry2.getValue()+
+//                 "</td><td>" + entry2.getValue().getClass().getName() + "</td>");
+//              out.println("</tr>");
+//
+//              if (entry2.getValue() instanceof Binding &&
+//                 ((Binding)entry2.getValue()).getQueue() instanceof Queue)
+//              {
+//                  Queue queue =
+//                     ((Binding)entry2.getValue()).getQueue();
+//                  List undelivered = queue.undelivered(null);
+//                  if (!undelivered.isEmpty())
+//                  {
+//                      out.println("<tr><td>List of undelivered messages on Paging</td>");
+//
+//                      out.println("<td colspan=2><table border=1>");
+//                      out.println("<tr><td>Reference#</td><td>Message</td></tr>");
+//                      for (Iterator i = undelivered.iterator();i.hasNext();)
+//                      {
+//                          SimpleMessageReference reference = (SimpleMessageReference)i.next();
+//                          out.println("<tr><td>" + reference.getInMemoryChannelCount() +
+//                             "</td><td>" + reference.getMessage() +"</td></tr>");
+//                      }
+//                      out.println("</table></td>");
+//                      out.println("</tr>");
+//                  }
+//              }
+//          }
+//      }
+//
+//      out.println("</table>");
+//      out.println("<br>Ocurrencies of conditionMap:");
+//      out.println("<table border=1>");
+//      out.println("<tr><td>EntryName</td><td>Value</td>");
+//
+//      for (Iterator iterConditions = conditionMap.entrySet().iterator();iterConditions.hasNext();)
+//      {
+//          Map.Entry entry = (Map.Entry)iterConditions.next();
+//          out.println("<tr><td>" + entry.getKey() + "</td><td>" + entry.getValue() + "</td></tr>");
+//
+//          if (entry.getValue() instanceof Bindings)
+//          {
+//              out.println("<tr><td>Binding Information:</td><td>");
+//              out.println("<table border=1>");
+//              out.println("<tr><td>Binding</td><td>Queue</td></tr>");
+//              Bindings bindings = (Bindings)entry.getValue();
+//              for (Iterator i = bindings.getAllBindings().iterator();i.hasNext();)
+//              {
+//
+//                  Binding binding = (Binding)i.next();
+//                  out.println("<tr><td>" + binding + "</td><td>" + binding.getQueue() +
+//                     "</td></tr>");
+//              }
+//              out.println("</table></td></tr>");
+//          }
+//      }
+//      out.println("</table>");
+//          
+//      out.println("Replicator's Information");
+//
+//      out.println("<table border=1><tr><td>Node</td><td>Key</td><td>Value</td></tr>");
+//
+//      for (Iterator iter = replicatedData.entrySet().iterator(); iter.hasNext();)
+//      {
+//         Map.Entry entry = (Map.Entry) iter.next();
+//         Map subMap = (Map)entry.getValue();
+//
+//         for (Iterator subIterator = subMap.entrySet().iterator(); subIterator.hasNext();)
+//         {
+//            Map.Entry subValue = (Map.Entry) subIterator.next();
+//            out.println("<tr><td>" + entry.getKey() + "</td>");
+//            out.println("<td>" + subValue.getKey() + "</td><td>" + subValue.getValue() + "</td></tr>" );
+//         }
+//
+//      }
+//
+//      out.println("</table>");
+//      
+//      return buffer.toString();
+   	
+   	return "";
+   }
+
+   // Package protected ----------------------------------------------------------------------------
+
+   // Protected ------------------------------------------------------------------------------------
+   
+   // Private ------------------------------------------------------------------------------------
+     
+   private void calculateFailoverMap()
+   {
+   	 //calculate the failover map
+      synchronized (failoverMap)
+   	{
+	   	// A node-address mapping has been added/removed from global state, we need to update
+	      // the failover map.
+	      failoverMap = failoverMapper.generateMapping(nodeIDAddressMap.keySet());
+   	}
+   }
+   
+   private Collection getBindings(String queueName) throws Exception
+   {
+   	bindingsLock.readLock().acquire();
+
+   	try
+   	{
+   		Iterator iter = this.mappings.entrySet().iterator();
+   		
+   		List bindings = new ArrayList();
+   		
+   		while (iter.hasNext())
+   		{
+   			Map.Entry entry = (Map.Entry)iter.next();
+   			
+   			Condition condition = (Condition)entry.getKey();
+   			
+   			List queues = (List)entry.getValue();
+   			
+   			Iterator iter2 = queues.iterator();
+   			
+   			while (iter2.hasNext())
+   			{
+   				Queue queue = (Queue)iter2.next();
+   				
+   				if (queueName == null || queue.getName().equals(queueName))
+   				{
+   					bindings.add(new Binding(condition, queue));
+   				}
+   			}
+   		}
+   		
+   		return bindings;
+   	}
+   	finally
+   	{
+   		bindingsLock.readLock().release();
+   	}
+   }
+
+   
+   private boolean routeInternal(MessageReference ref, Condition condition, Transaction tx, boolean fromCluster) throws Exception
+   {
+   	if (trace) { log.trace(this + " routing " + ref + " with condition '" +
+   			                 condition + "'" + (tx == null ? "" : " transactionally in " + tx) + 
+   			                 " from cluster " + fromCluster); }
+   	
+      boolean routed = false;
+
+      bindingsLock.readLock().acquire();
+      
+      try
+      {
+         List queues = (List)mappings.get(condition);
+         
+         if (queues != null)
+         {
+         	Iterator iter = queues.iterator();
+         	
+         	int localReliableCount = 0;
+         	
+         	Set remoteSet = null;
+         	
+         	List targets = new ArrayList();
+         	
+         	log.info("routing to " + queues.size() + " queues");
+         	
+         	while (iter.hasNext())
+         	{
+         		Queue queue = (Queue)iter.next();
+         		
+         		//TODO optimise this
+         		
+         		if (queue.getNodeID() == thisNodeID)
+         		{
+         			//Local queue
+
+         			//TODO - There is a temporary hack here -
+         			//When routing to a clustered temp queue, the queue is unreliable - but we always want to route to the local
+         			//one so we need to add the check that we only route remotely if it's a topic
+         			//We could do this better by making sure that only one queue with the same name is routed to on the cluster
+         			if (!fromCluster || (!queue.isRecoverable() && !((JMSCondition)condition).isQueue()))
+         			{
+         				//If we're not routing from the cluster OR the queue is unreliable then we consider it
+         				
+         				//When we route from the cluster we never route to reliable queues
+         				
+	         			Filter filter = queue.getFilter();
+	         			
+	         			if (filter == null || filter.accept(ref.getMessage()))
+	         			{                		
+	         				log.info("Added queue " + queue + " to list of targets");
+	      					targets.add(queue);
+	      					
+	      					if (ref.getMessage().isReliable() && queue.isRecoverable())
+	         				{
+	         					localReliableCount++;
+	         				}         				
+	         			}   
+         			}
+         		}
+         		else if (!fromCluster)
+         		{
+         			//Remote queue
+         			
+         			if (!queue.isRecoverable())
+         			{	         			
+         				//When we send to the cluster we never send to reliable queues
+         				
+	         			Filter filter = queue.getFilter();
+	         			
+	         			if (filter == null || filter.accept(ref.getMessage()))
+	         			{
+	         				if (remoteSet == null)
+	         				{
+	         					remoteSet = new HashSet();
+	         				}
+	         				
+	         				remoteSet.add(new Integer(queue.getNodeID()));
+	         			}
+         			}
+         		}
+         	}
+         	
+         	if (remoteSet != null)
+         	{
+         		//There are queues on other nodes that want the message too
+         		
+         		//If the message is non reliable then we can unicast or multicast the message to the group so it
+         		//can get picked up by other nodes
+         		
+         		ClusterRequest request = new MessageRequest(condition.toText(), ref.getMessage());
+         		
+         		if (remoteSet.size() == 1)
+         		{
+         			//Only one node requires the message, so we can unicast
+         			
+         			unicastRequest(request, thisNodeID);
+         		}
+         		else
+         		{
+         			//More than one node requires the message - so we multicast         			
+         			//Whether it is reliable or unreliable multicast is determined by the JGroups stack config
+         			
+         			multicastRequest(request);
+         		}
+         	}
+         	else
+         	{
+         		log.info("************** &&&&&&&&&& not multicasting");
+         	}
+         	
+         	//If the ref is reliable and there is more than one reliable local queue that accepts the message then we need
+         	//to route in a transaction to guarantee once and only once reliability guarantee
+         	
+         	boolean startedTx = false;
+         	
+         	if (tx == null && localReliableCount > 1)
+         	{
+         		if (trace) { log.trace("Starting internal tx, reliableCount = " + localReliableCount); }
+         		
+         		tx = tr.createTransaction();
+         		
+         		startedTx = true;
+         	}
+         	
+         	//Now actually route the ref
+         	
+         	iter = targets.iterator();
+         	
+         	while (iter.hasNext())
+         	{
+         		Queue queue = (Queue)iter.next();
+         		
+         		if (trace) { log.trace("Routing ref to queue " + queue); }
+         		         	
+         		log.info("Routing ref " + ref + " to queue " + queue);
+         		
+         		Delivery del = queue.handle(null, ref, tx);
+         		
+         		if (trace) { log.trace("Queue returned " + del); }
+
+               if (del != null && del.isSelectorAccepted())
+               {
+                  routed = true;
+               }
+         	}
+         	
+            if (startedTx)
+            {
+               if (trace) { log.trace(this + " committing " + tx); }
+               
+               tx.commit();
+               
+               if (trace) { log.trace(this + " committed " + tx); }
+            }
+         }
+      }
+      finally
+      {
+         bindingsLock.readLock().release();
+      }
+
+      return routed;
+   }   
+   
+   private void removeBindingInMemory(Binding binding)
+   {
+   	Queue queue = binding.queue;
+   	
+   	Condition condition = binding.condition;
+   	
+   	if (queue.getNodeID() == this.thisNodeID)
+   	{
+   		Binding b = (Binding)nameMap.remove(queue.getName());
+   		
+   		if (b == null)
+   		{
+   			throw new IllegalStateException("Cannot find binding in name map for queue " + queue.getName());
+   		}
+   		
+   		b = (Binding)channelIDMap.remove(new Long(queue.getChannelID()));
+   		
+   		if (b == null)
+   		{
+   			throw new IllegalStateException("Cannot find binding in channel id map for queue " + queue.getName());
+   		}
+   	}
+   	
+   	List queues = (List)mappings.get(condition);
+	      
+      if (queues == null)
+      {
+      	throw new IllegalStateException("Cannot find queues in condition map for condition " + condition);
+      }	     
+      
+      boolean removed = queues.remove(queue);
+      
+      if (!removed)
+      {
+      	throw new IllegalStateException("Cannot find queue in list for queue " + queue.getName());
+      }
+      
+      if (queues.isEmpty())
+      {
+      	mappings.remove(condition);
+      }
+      
+      // Send a notification
+      ClusterNotification notification = new ClusterNotification(ClusterNotification.TYPE_UNBIND, queue.getNodeID(), queue.getName());
+      
+      clusterNotifier.sendNotification(notification);
+   }
+   
+   private void addBindingInMemory(Binding binding)
+   {
+   	Queue queue = binding.queue;
+   	
+   	//The name map and the channel id map only hold the bindings for the *current* node
+   	
+   	if (queue.getNodeID() == this.thisNodeID)
+   	{	   	
+	   	if (nameMap.get(queue.getName()) != null)
+	   	{
+	   		throw new IllegalArgumentException("Cannot bind queue, it is already bound " + queue.getName());
+	   	}
+	   	
+	   	log.info("*********** putting queue name " + queue.getName() + " in map");
+	   	nameMap.put(queue.getName(), binding);
+	   	
+	   	channelIDMap.put(new Long(queue.getChannelID()), binding);
+   	}
+   	
+   	Condition condition = binding.condition;   	
+   	
+   	List queues = (List)mappings.get(condition);
+   	
+   	if (queues == null)
+   	{
+   		queues = new ArrayList();
+   		
+   		if (queues.contains(queue))
+   		{
+   			throw new IllegalArgumentException("Queue is already bound with condition " + condition);
+   		}
+   		
+   		mappings.put(condition, queues);
+   	}
+   	
+   	queues.add(queue);   
+   	
+      //Send a notification
+      ClusterNotification notification = new ClusterNotification(ClusterNotification.TYPE_BIND, queue.getNodeID(), queue.getName());
+      
+      clusterNotifier.sendNotification(notification);
+   }
+   
+   /*
+    * Multicast a message to all members of the group
+    */
+   private void multicastRequest(ClusterRequest request) throws Exception
+   {
+      if (stopping)
+      {
+         return;
+      }
+      
+      if (trace) { log.trace(this + " Unicasting request " + request); }
+      
+      groupMember.multicastRequest(request);
+   }
+
+   /*
+    * Unicast a message to one member of the group
+    */
+   private void unicastRequest(ClusterRequest request, int nodeId) throws Exception
+   {
+      if (stopping)
+      {
+         return;
+      }
+      
+      Address address = this.getAddressForNodeId(nodeId, false);
+
+      if (address == null)
+      {
+         throw new IllegalArgumentException("Cannot find address for node " + nodeId);
+      }
+      
+      if (trace) { log.trace(this + "Unicasting request " + request + " to node " + nodeId); }
+
+      groupMember.unicastRequest(request, address);
+   }
+   
+   private void loadBindingsFromStorage() throws Exception
+   {
+      bindingsLock.writeLock().acquire();
+
+      Connection conn = null;
+      PreparedStatement ps  = null;
+      ResultSet rs = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+
+      try
+      {
+         conn = ds.getConnection();
+
+         ps = conn.prepareStatement(getSQLStatement("LOAD_BINDINGS"));
+
+         ps.setString(1, officeName);
+         
+         ps.setInt(2, thisNodeID);
+
+         rs = ps.executeQuery();
+
+         while (rs.next())
+         {
+            String queueName = rs.getString(1);
+            String conditionText = rs.getString(2);
+            String selector = rs.getString(3);
+
+            if (rs.wasNull())
+            {
+               selector = null;
+            }
+
+            long channelID = rs.getLong(4);
+                       
+            boolean bindingClustered = rs.getString(5).equals("Y");
+            
+            //If the node is not clustered then we load the bindings as non clustered
+                    	
+            Filter filter = null;
+            
+            if (selector != null)
+            {
+            	filter = filterFactory.createFilter(selector);
+            }
+            
+            Queue queue = new MessagingQueue(thisNodeID, queueName, channelID, ms, pm,
+                                             true, filter, bindingClustered && clustered);
+            
+            log.info("**** loaded binding from storage: " + queueName);
+            
+            Condition condition = conditionFactory.createCondition(conditionText);
+            
+            addBindingInMemory(new Binding(condition, queue));          
+            
+            //Need to broadcast it too
+            if (clustered && queue.isClustered())
+            {
+            	String filterString = queue.getFilter() == null ? null : queue.getFilter().getFilterString();      	            	
+            	
+            	MappingInfo info = new MappingInfo(thisNodeID, queue.getName(), condition.toText(), filterString, queue.getChannelID(),
+            			                             queue.isRecoverable(), true,
+            			                             queue.getFullSize(), queue.getPageSize(), queue.getDownCacheSize(),
+            			                             queue.getMaxSize(),
+            			                             queue.isPreserveOrdering());
+            	
+               ClusterRequest request = new BindRequest(info, false);
+
+               syncSendRequest(request);         
+            }
+         }
+      }
+      catch (Exception e)
+      {
+      	wrap.exceptionOccurred();
+      	throw e;
+      }
+      finally
+      {
+         bindingsLock.writeLock().release();
+         
+         closeResultSet(rs);
+         
+         closeStatement(ps);
+         
+         closeConnection(conn);
+
+         wrap.end();
+      }
+   }
+
+   private void insertBindingInStorage(Condition condition, Queue queue) 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, officeName);
+         ps.setInt(2, thisNodeID);
+         ps.setString(3, queue.getName());
+         ps.setString(4, condition.toText());
+         String filterString = queue.getFilter() != null ? queue.getFilter().getFilterString() : null;
+         if (filterString != null)
+         {
+            ps.setString(5, filterString);
+         }
+         else
+         {
+            ps.setNull(5, Types.VARCHAR);
+         }
+         ps.setLong(6, queue.getChannelID());        
+         if (queue.isClustered())
+         {
+            ps.setString(7, "Y");
+         }
+         else
+         {
+            ps.setString(7, "N");
+         }
+
+         ps.executeUpdate();
+      }
+      catch (Exception e)
+      {
+      	wrap.exceptionOccurred();
+      	throw e;
+      }
+      finally
+      {
+      	closeStatement(ps);
+      	closeConnection(conn);
+         wrap.end();
+      }
+   }
+
+   private boolean deleteBindingFromStorage(Queue queue) 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.officeName);
+         ps.setInt(2, queue.getNodeID());
+         ps.setString(3, queue.getName());
+
+         int rows = ps.executeUpdate();
+
+         return rows == 1;
+      }
+      catch (Exception e)
+      {
+      	wrap.exceptionOccurred();
+      	throw e;
+      }
+      finally
+      {
+      	closeStatement(ps);
+      	closeConnection(conn);
+         wrap.end();
+      }
+   }
+
+   private boolean leaveMessageReceived(Integer nodeId) throws Exception
+   {
+      synchronized (leftSet)
+      {
+         return leftSet.remove(nodeId);
+      }
+   }
+
+   /*
+    * Removes all binding data, and any replicant data for the specified node.
+    */
+   private void cleanDataForNode(Integer nodeToRemove) throws Exception
+   {
+      log.debug(this + " cleaning data for node " + nodeToRemove);
+
+      bindingsLock.writeLock().acquire();
+
+      log.info("** cleaning data for node " + nodeToRemove);
+      
+      try
+      {
+      	Iterator iter = mappings.entrySet().iterator();
+      	
+      	List toRemove = new ArrayList();
+      	
+      	while (iter.hasNext())
+      	{
+      		Map.Entry entry = (Map.Entry)iter.next();
+      		
+      		Condition condition = (Condition)entry.getKey();
+      		
+      		List queues = (List)entry.getValue();
+      		
+      		Iterator iter2 = queues.iterator();
+      		
+      		while (iter2.hasNext())
+      		{
+      			Queue queue = (Queue)iter2.next();
+      			
+      			if (queue.getNodeID() == nodeToRemove.intValue())
+      			{
+      				log.info("** removing queue " + queue);
+      				
+      				toRemove.add(new Binding(condition, queue));
+      			}
+      			else
+      			{
+      				log.info("** not removing " + queue);
+      			}
+      		}
+      	}
+      	
+      	iter = toRemove.iterator();
+      	
+      	while (iter.hasNext())
+      	{
+      		Binding binding = (Binding)iter.next();
+
+      		removeBindingInMemory(binding);
+      	}
+      }
+      finally
+      {
+         bindingsLock.writeLock().release();
+      }
+
+      Map toNotify = new HashMap();
+      
+      synchronized (replicatedData)
+      {
+         // We need to remove any replicant data for the node.
+         for (Iterator i = replicatedData.entrySet().iterator(); i.hasNext(); )
+         {
+            Map.Entry entry = (Map.Entry)i.next();
+            String key = (String)entry.getKey();
+            Map replicants = (Map)entry.getValue();
+
+            replicants.remove(nodeToRemove);
+
+            if (replicants.isEmpty())
+            {
+               i.remove();
+            }
+
+            toNotify.put(key, replicants);           
+         }
+      }
+      
+      //remove node id - address info
+      nodeIDAddressMap.remove(nodeToRemove);      
+      
+      //Recalculate the failover map
+      calculateFailoverMap();
+      
+      //Notify outside the lock to prevent deadlock
+      
+      //Send notifications for the replicant data removed
+      
+      for (Iterator i = toNotify.entrySet().iterator(); i.hasNext(); )
+      {
+         Map.Entry entry = (Map.Entry)i.next();
+         String key = (String)entry.getKey();
+
+         ClusterNotification notification = new ClusterNotification(ClusterNotification.TYPE_REPLICATOR_REMOVE, nodeToRemove.intValue(), key);
+         
+         clusterNotifier.sendNotification(notification);
+      }
+   }
+
+   /*
+    * Multicast a sync request
+    */
+   private void syncSendRequest(ClusterRequest request) throws Exception
+   {
+      if (stopping)
+      {
+         return;
+      }
+      
+      if (trace) { log.trace(this + " sending sync request " + request); }
+      
+      groupMember.sendSyncRequest(request);
+   }
+
+   //TODO - can optimise this with a reverse map
+   private Integer getNodeIDForSyncAddress(Address address) throws Exception
+   {
+   	Iterator iter = nodeIDAddressMap.entrySet().iterator();
+   	
+   	Integer nodeID = null;
+   	
+   	while (iter.hasNext())
+   	{
+   		Map.Entry entry = (Map.Entry)iter.next();
+   			
+   		PostOfficeAddressInfo info = (PostOfficeAddressInfo)entry.getValue();
+   		
+   		if (info.getSyncChannelAddress().equals(address))
+   		{
+   			nodeID = (Integer)entry.getKey();
+   			
+   			break;
+   		}
+   	}   	
+   	
+   	return nodeID;   	
+   }
+   	      
+   private boolean knowAboutNodeId(int nodeID)
+   {
+   	return nodeIDAddressMap.get(new Integer(nodeID)) != null;   	
+   }
+
+   private Map copyReplicatedData(Map toCopy)
+   {
+      Map copy = new HashMap();
+
+      Iterator iter = toCopy.entrySet().iterator();
+
+      while (iter.hasNext())
+      {
+         Map.Entry entry = (Map.Entry)iter.next();
+
+         Serializable key = (Serializable)entry.getKey();
+
+         Map replicants = (Map)entry.getValue();
+
+         Map m = new LinkedHashMap();
+
+         m.putAll(replicants);
+
+         copy.put(key, m);
+      }
+
+      return copy;
+   }
+
+   private Address getAddressForNodeId(int nodeId, boolean sync) throws Exception
+   {   	
+   	PostOfficeAddressInfo info = (PostOfficeAddressInfo)nodeIDAddressMap.get(new Integer(nodeId));
+   	
+   	if (info == null)
+   	{
+   		return null;
+   	}
+   	else if (sync)
+   	{
+   		return info.getSyncChannelAddress();
+   	}
+   	else
+   	{
+   		return info.getAsyncChannelAddress();
+   	}     	
+   }
+   
+
+   /**
+    * This method fails over all the queues from node <failedNodeId> onto this node. It is triggered
+    * when a JGroups view change occurs due to a member leaving and it's determined the member
+    * didn't leave cleanly.
+    * 
+    * On failover we basically merge any queues with the same name on the failed node into any corresponding queue
+    * on this node
+    */
+   private void performFailover(Integer failedNodeID) throws Exception
+   {
+      log.debug(this + " performing failover for failed node " + failedNodeID);
+      
+      ClusterNotification notification = new ClusterNotification(ClusterNotification.TYPE_FAILOVER_START, failedNodeID.intValue(), null);
+      
+      clusterNotifier.sendNotification(notification);
+
+      log.debug(this + " announced it is starting failover procedure");
+   	
+      // Need to lock
+      bindingsLock.writeLock().acquire();
+
+      try
+      {
+         Iterator iter = mappings.entrySet().iterator();
+         	
+      	List toRemove = new ArrayList();
+      	
+      	while (iter.hasNext())
+      	{
+      		Map.Entry entry = (Map.Entry)iter.next();
+      		
+      		Condition condition = (Condition)entry.getKey();
+      		
+      		List queues = (List)entry.getValue();
+      		
+      		Iterator iter2 = queues.iterator();
+      		
+      		while (iter2.hasNext())
+      		{
+      			Queue queue = (Queue)iter2.next();
+      			
+      			if (queue.isRecoverable() && queue.getNodeID() == failedNodeID.intValue())
+      			{
+      				toRemove.add(new Binding(condition, queue));
+      			}
+      		}
+      	}
+         	
+      	iter = toRemove.iterator();
+      	
+      	while (iter.hasNext())
+      	{
+      		Binding binding = (Binding)iter.next();
+      		
+      		Condition condition = binding.condition;
+      		
+      		Queue queue = binding.queue;
+      		
+      		// Sanity check
+            if (!queue.isRecoverable())
+            {
+               throw new IllegalStateException("Found non recoverable queue " +
+                                               queue.getName() + "in map, these should have been removed!");
+            }
+
+            // Sanity check
+            if (!queue.isClustered())
+            {
+               throw new IllegalStateException("Queue " + queue.getName() +
+                                               " is not clustered!");
+            }
+      		
+            //Remove from the in-memory map
+            removeBindingInMemory(binding);
+      		
+      		//Delete from storage
+      		deleteBindingFromStorage(queue);
+      	
+            log.debug(this + " deleted binding for " + queue.getName());
+
+            // Note we do not need to send an unbind request across the cluster - this is because
+            // when the node crashes a view change will hit the other nodes and that will cause
+            // all binding data for that node to be removed anyway.
+            
+            Collection queues = getQueuesForCondition(condition, true);
+            
+            Iterator iter2 = queues.iterator();
+            
+            Queue localQueue = null;
+            
+            while (iter2.hasNext())
+            {
+            	Queue q = (Queue)iter2.next();
+            	
+            	if (queue.getName().equals(q.getName()))
+            	{
+            		localQueue = q;
+            		
+            		break;
+            	}
+            	
+            }
+            	
+            if (localQueue != null)
+            {
+               //need to merge the queues
+            	
+            	log.debug(this + " has already a queue: " + queue.getName() + " queue so merging queues");
+            	  
+               localQueue.mergeIn(queue.getChannelID());
+               
+               log.debug("Merged queue");       
+            }
+            else
+            {
+            	log.debug(this + " did not have a queue: " + queue.getName() + " queue so no need to merge");
+            	
+              	Queue newQueue = new MessagingQueue(thisNodeID, queue.getName(), queue.getChannelID(), queue.isRecoverable(),
+              			                              queue.getFilter(), true);
+
+               addBinding(new Binding(condition, newQueue), false);
+               
+               newQueue.deactivate();
+               
+               newQueue.load();
+               
+               //TODO - do we really want to activate ALL the queues - surely only the ones that correspond to deployed destinations??
+               newQueue.activate();
+
+               //FIXME there is a problem in the above code.
+               //If the server crashes between deleting the binding from the database
+               //and creating the new binding in the database, then the binding will be completely
+               //lost from the database when the server is resurrected.
+               //To remedy, both db operations need to be done in the same JBDC tx
+            }            
+         }
+
+         log.debug(this + " finished failing over destinations");
+        
+         log.info(this + ": server side fail over is now complete");
+      }
+      finally
+      {
+         bindingsLock.writeLock().release();
+      }
+      
+      log.debug(this + " announcing that failover procedure is complete");
+
+      notification = new ClusterNotification(ClusterNotification.TYPE_FAILOVER_END, failedNodeID.intValue(), null);
+      
+      clusterNotifier.sendNotification(notification);
+      
+      //for testing only
+      this.sendJMXNotification(FAILOVER_COMPLETED_NOTIFICATION);
+
+   }
+
+   private void sendJMXNotification(String notificationType)
+   {
+      Notification n = new Notification(notificationType, "", 0l);
+      nbSupport.sendNotification(n);
+      log.debug(this + " sent " + notificationType + " JMX notification");
+   }
+
+   // Inner classes --------------------------------------------------------------------------------
+
+}
\ No newline at end of file

Added: trunk/src/main/org/jboss/messaging/core/impl/postoffice/PostOfficeAddressInfo.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/PostOfficeAddressInfo.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/PostOfficeAddressInfo.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,130 @@
+/*
+ * 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.impl.postoffice;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.Serializable;
+
+import org.jboss.messaging.util.Streamable;
+import org.jgroups.Address;
+import org.jgroups.stack.IpAddress;
+
+/**
+ * 
+ * A PostOfficeAddressInfo
+ * 
+ * Holds the addresses used by a clustered post office
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1917 $</tt>
+ *
+ * $Id: PostOfficeAddressInfo.java 1917 2007-01-08 20:26:12Z clebert.suconic at jboss.com $
+ *
+ */
+class PostOfficeAddressInfo implements Streamable, Serializable
+{
+   // Constants -----------------------------------------------------
+
+   private static final long serialVersionUID = 8462102430717730566L;
+
+   // Static --------------------------------------------------------
+
+   // Attributes ----------------------------------------------------
+
+   private Address syncChannelAddress;
+   private Address asyncChannelAddress;
+
+   // Constructors --------------------------------------------------
+
+   PostOfficeAddressInfo()
+   {
+   }
+
+   PostOfficeAddressInfo(Address syncChannelAddress, Address asyncChannelAddress)
+   {
+      this.syncChannelAddress = syncChannelAddress;
+      this.asyncChannelAddress = asyncChannelAddress;
+   }
+
+   // Streamable implementation -------------------------------------
+
+   public void read(DataInputStream in) throws Exception
+   {
+      syncChannelAddress = new IpAddress();
+
+      syncChannelAddress.readFrom(in);
+
+      asyncChannelAddress = new IpAddress();
+
+      asyncChannelAddress.readFrom(in);
+   }
+
+   public void write(DataOutputStream out) throws Exception
+   {
+      if (!(syncChannelAddress instanceof IpAddress))
+      {
+         throw new IllegalStateException("Address must be IpAddress");
+      }
+
+      if (!(asyncChannelAddress instanceof IpAddress))
+      {
+         throw new IllegalStateException("Address must be IpAddress");
+      }
+
+      syncChannelAddress.writeTo(out);
+
+      asyncChannelAddress.writeTo(out);
+   }
+
+   // Public --------------------------------------------------------
+
+   public String toString()
+   {
+      StringBuffer sb = new StringBuffer("[");
+      sb.append("synch addr ").append(syncChannelAddress);
+      sb.append(", asynch addr ").append(asyncChannelAddress);
+      sb.append("]");
+
+      return sb.toString();
+   }
+
+
+   // Package protected ---------------------------------------------
+
+   Address getSyncChannelAddress()
+   {
+      return syncChannelAddress;
+   }
+
+   Address getAsyncChannelAddress()
+   {
+      return asyncChannelAddress;
+   }
+
+   // Protected -----------------------------------------------------
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/postoffice/PutReplicantRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/PutReplicantRequest.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/PutReplicantRequest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,116 @@
+/*
+ * 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.impl.postoffice;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.Serializable;
+
+import org.jboss.messaging.util.StreamUtils;
+
+
+/**
+ * 
+ * A PutReplicantRequest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1917 $</tt>
+ *
+ * $Id: PutReplicantRequest.java 1917 2007-01-08 20:26:12Z clebert.suconic at jboss.com $
+ *
+ */
+class PutReplicantRequest extends ClusterRequest
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+
+   // Attributes ----------------------------------------------------
+
+   private int nodeId;
+   private Serializable key;
+   private Serializable replicant;
+
+   // Constructors --------------------------------------------------
+
+   PutReplicantRequest()
+   {
+   }
+
+   PutReplicantRequest(int nodeId, Serializable key, Serializable replicant)
+   {
+      this.nodeId = nodeId;
+
+      this.key = key;
+
+      this.replicant = replicant;
+   }
+
+   // Streamable implementation -------------------------------------
+
+   public void read(DataInputStream in) throws Exception
+   {
+      nodeId = in.readInt();
+
+      key = (Serializable)StreamUtils.readObject(in, true);
+
+      replicant = (Serializable)StreamUtils.readObject(in, true);
+   }
+
+   public void write(DataOutputStream out) throws Exception
+   {
+      out.writeInt(nodeId);
+
+      StreamUtils.writeObject(out, key, true, true);
+
+      StreamUtils.writeObject(out, replicant, true, true);
+   }
+
+   // ClusterRequest overrides --------------------------------------
+
+   Object execute(RequestTarget office) throws Exception
+   {
+      office.putReplicantLocally(nodeId, key, replicant);
+      return null;
+   }
+
+   byte getType()
+   {
+      return ClusterRequest.PUT_REPLICANT_REQUEST;
+   }
+
+   // Public --------------------------------------------------------
+
+   public String toString()
+   {
+      return "PutRequest[" + key + "][" + replicant + "]";
+   }
+
+   // Package protected ---------------------------------------------
+
+   // Protected -----------------------------------------------------
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/postoffice/RemoveReplicantRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/RemoveReplicantRequest.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/RemoveReplicantRequest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,83 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.impl.postoffice;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.Serializable;
+
+import org.jboss.messaging.util.StreamUtils;
+
+/**
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: $</tt>19 Jun 2007
+ *
+ * $Id: $
+ *
+ */
+class RemoveReplicantRequest extends ClusterRequest
+{
+   private int nodeId;
+   
+   private Serializable key;
+
+   RemoveReplicantRequest()
+   {      
+   }
+   
+   RemoveReplicantRequest(int nodeId, Serializable key)
+   {
+      this.nodeId = nodeId;  
+      
+      this.key = key;
+   }
+   
+   Object execute(RequestTarget office) throws Exception
+   {
+      if (!office.removeReplicantLocally(nodeId, key))
+      {
+         throw new IllegalStateException("Failed to remove replicant locally: " + nodeId + " key: "+ key);
+      }
+      
+      return null;
+   }
+   
+   byte getType()
+   {
+      return ClusterRequest.REMOVE_REPLICANT_REQUEST;
+   }
+
+   public void read(DataInputStream in) throws Exception
+   {
+      nodeId = in.readInt();
+      
+      key = (Serializable)StreamUtils.readObject(in, true);
+   }
+
+   public void write(DataOutputStream out) throws Exception
+   {
+      out.writeInt(nodeId);   
+      
+      StreamUtils.writeObject(out, key, true, true);
+   }
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/postoffice/RequestTarget.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/RequestTarget.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/RequestTarget.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.impl.postoffice;
+
+import java.io.Serializable;
+
+import org.jboss.messaging.core.contract.Message;
+
+/**
+ * 
+ * This interface contains the methods that ClusterRequest instances can call
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 2421 $</tt>
+ *
+ * $Id: PostOfficeInternal.java 2421 2007-02-25 00:06:06Z timfox $
+ *
+ */
+interface RequestTarget
+{		
+   void addBindingFromCluster(MappingInfo mapping, boolean allNodes) throws Exception;
+   
+   void removeBindingFromCluster(MappingInfo mapping, boolean allNodes) throws Throwable;
+ 
+   void handleNodeJoined(int nodeId, PostOfficeAddressInfo info) throws Exception;
+   
+   void handleNodeLeft(int nodeId) throws Exception;
+   
+   void putReplicantLocally(int nodeId, Serializable key, Serializable replicant) throws Exception;
+   
+   boolean removeReplicantLocally(int nodeId, Serializable key) throws Exception;
+   
+   void routeFromCluster(Message message, String routingKeyText) throws Exception;
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/postoffice/SharedState.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/SharedState.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/SharedState.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.messaging.core.impl.postoffice;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.jboss.messaging.util.StreamUtils;
+import org.jboss.messaging.util.Streamable;
+
+/**
+ * A SharedState
+ * 
+ * This encapsulates the shared state maintained across the cluster
+ * This comprise the bindings, and the arbitrary replicated data
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1917 $</tt>
+ *
+ * $Id: SharedState.java 1917 2007-01-08 20:26:12Z clebert.suconic at jboss.com $
+ *
+ */
+class SharedState implements Streamable
+{  
+   private List mappings;
+   
+   private Map replicatedData;
+   
+   private Map nodeIDAddressMap;
+   
+   SharedState()
+   {      
+   }
+   
+   SharedState(List mappings, Map replicatedData, Map nodeIDAddressMap)
+   {
+      this.mappings = mappings;
+      
+      this.replicatedData = replicatedData;
+      
+      this.nodeIDAddressMap = nodeIDAddressMap;
+   }
+   
+   List getMappings()
+   {
+      return mappings;
+   }
+   
+   Map getReplicatedData()
+   {
+      return replicatedData;
+   }
+   
+   Map getNodeIDAddressMap()
+   {
+   	return nodeIDAddressMap;
+   }
+
+   public void read(DataInputStream in) throws Exception
+   {
+      int size = in.readInt();      
+      
+      mappings = new ArrayList(size);
+      
+      for (int i = 0; i < size; i++)
+      {
+         MappingInfo mapping = new MappingInfo();
+         
+         mapping.read(in);
+         
+         mappings.add(mapping);
+      }
+      
+      size = in.readInt();
+      
+      replicatedData = new HashMap(size);
+      
+      for (int i = 0; i < size; i++)
+      {
+         Serializable key = (Serializable)StreamUtils.readObject(in, true);
+         
+         HashMap replicants = StreamUtils.readMap(in, false);
+         
+         replicatedData.put(key, replicants);
+      }
+      
+      size = in.readInt();
+      
+      nodeIDAddressMap = new HashMap(size);
+      
+      for (int i = 0; i < size; i++)
+      {
+      	int nodeID = in.readInt();
+      	
+      	PostOfficeAddressInfo info = new PostOfficeAddressInfo();
+      	
+      	info.read(in);
+      	
+      	nodeIDAddressMap.put(new Integer(nodeID), info);
+      }
+   }
+
+   public void write(DataOutputStream out) throws Exception
+   {
+      out.writeInt(mappings.size());
+      
+      Iterator iter = mappings.iterator();
+      
+      while (iter.hasNext())
+      {
+         MappingInfo mapping = (MappingInfo)iter.next();
+         
+         mapping.write(out);
+      }
+      
+      out.writeInt(replicatedData.size());
+      
+      iter = replicatedData.entrySet().iterator();
+      
+      while (iter.hasNext())
+      {
+         Map.Entry entry = (Map.Entry)iter.next();
+         
+         Serializable key = (Serializable)entry.getKey();         
+         
+         StreamUtils.writeObject(out, key, true, true);
+         
+         Map replicants = (Map)entry.getValue();
+         
+         StreamUtils.writeMap(out, replicants, false);
+      }
+      
+      out.writeInt(nodeIDAddressMap.size());
+      
+      iter = nodeIDAddressMap.entrySet().iterator();
+      
+      while (iter.hasNext())
+      {
+      	Map.Entry entry = (Map.Entry)iter.next();
+      	
+      	Integer nodeID = (Integer)entry.getKey();
+      	
+      	PostOfficeAddressInfo info = (PostOfficeAddressInfo)entry.getValue();
+      	
+      	out.writeInt(nodeID.intValue());
+      	
+      	info.write(out);
+      }
+   }
+}

Added: trunk/src/main/org/jboss/messaging/core/impl/postoffice/UnbindRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/UnbindRequest.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/UnbindRequest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.impl.postoffice;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+
+import org.jboss.logging.Logger;
+
+/**
+ * A UnbindRequest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1917 $</tt>
+ *
+ * $Id: UnbindRequest.java 1917 2007-01-08 20:26:12Z clebert.suconic at jboss.com $
+ *
+ */
+class UnbindRequest extends ClusterRequest
+{
+   private static final Logger log = Logger.getLogger(UnbindRequest.class);
+	
+   private MappingInfo mappingInfo; 
+   
+   private boolean allNodes;
+   
+   UnbindRequest()
+   {      
+   }
+
+   UnbindRequest(MappingInfo mappingInfo, boolean allNodes)
+   {
+      this.mappingInfo = mappingInfo;
+      
+      this.allNodes = allNodes;
+   }
+
+   Object execute(RequestTarget office) throws Exception
+   {
+   	try
+   	{
+   		office.removeBindingFromCluster(mappingInfo, allNodes);
+   	}
+   	catch (Throwable t)
+   	{
+   		final String s = "Failed to remove binding";
+   		log.error(s, t);
+   		throw new Exception(s, t);
+   	}
+      
+      return null;
+   }
+   
+   byte getType()
+   {
+      return ClusterRequest.UNBIND_REQUEST;
+   }
+
+   public void read(DataInputStream in) throws Exception
+   {
+      mappingInfo = new MappingInfo();
+      
+      mappingInfo.read(in);
+      
+      allNodes = in.readBoolean();
+   }
+
+   public void write(DataOutputStream out) throws Exception
+   {
+      mappingInfo.write(out);
+      
+      out.writeBoolean(allNodes);
+   }
+}

Copied: trunk/src/main/org/jboss/messaging/core/impl/tx (from rev 2781, trunk/src/main/org/jboss/messaging/core/tx)

Deleted: trunk/src/main/org/jboss/messaging/core/impl/tx/PreparedTxInfo.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/tx/PreparedTxInfo.java	2007-06-13 18:15:18 UTC (rev 2781)
+++ trunk/src/main/org/jboss/messaging/core/impl/tx/PreparedTxInfo.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,74 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005-2006, 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.tx;
-
-import javax.transaction.xa.Xid;
-
-/**
- * A value object for prepared transaction representation
- *
- * @author <a href="mailto:Konda.Madhu at uk.mizuho-sc.com">Madhu Konda</a>
- */
-public class PreparedTxInfo
-{
-
-   // Attributes --------------------------------------------------------------
-
-	private long txId;
-
-	private Xid xid = null;
-
-
-   // Constructors ------------------------------------------------------------
-
-	public PreparedTxInfo(long txId, Xid xid) {
-		setTxId(txId);
-		setXid(xid);
-	}
-
-
-   // Public ------------------------------------------------------------------
-
-	public long getTxId() {
-		return txId;
-	}
-
-	public void setTxId(long txId) {
-		this.txId = txId;
-	}
-
-	public Xid getXid() {
-		return xid;
-	}
-
-	public void setXid(Xid xid) {
-		this.xid = xid;
-	}
-
-
-   // Object overrides --------------------------------------------------------
-
-	public String toString()
-	{
-		return "Tx Id: "+getTxId()+" Xid: "+getXid();
-	}
-}
\ No newline at end of file

Copied: trunk/src/main/org/jboss/messaging/core/impl/tx/PreparedTxInfo.java (from rev 2795, trunk/src/main/org/jboss/messaging/core/tx/PreparedTxInfo.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/tx/PreparedTxInfo.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/tx/PreparedTxInfo.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,74 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2006, 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.impl.tx;
+
+import javax.transaction.xa.Xid;
+
+/**
+ * A value object for prepared transaction representation
+ *
+ * @author <a href="mailto:Konda.Madhu at uk.mizuho-sc.com">Madhu Konda</a>
+ */
+public class PreparedTxInfo
+{
+
+   // Attributes --------------------------------------------------------------
+
+	private long txId;
+
+	private Xid xid = null;
+
+
+   // Constructors ------------------------------------------------------------
+
+	public PreparedTxInfo(long txId, Xid xid) {
+		setTxId(txId);
+		setXid(xid);
+	}
+
+
+   // Public ------------------------------------------------------------------
+
+	public long getTxId() {
+		return txId;
+	}
+
+	public void setTxId(long txId) {
+		this.txId = txId;
+	}
+
+	public Xid getXid() {
+		return xid;
+	}
+
+	public void setXid(Xid xid) {
+		this.xid = xid;
+	}
+
+
+   // Object overrides --------------------------------------------------------
+
+	public String toString()
+	{
+		return "Tx Id: "+getTxId()+" Xid: "+getXid();
+	}
+}
\ No newline at end of file

Deleted: trunk/src/main/org/jboss/messaging/core/impl/tx/Transaction.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/tx/Transaction.java	2007-06-13 18:15:18 UTC (rev 2781)
+++ trunk/src/main/org/jboss/messaging/core/impl/tx/Transaction.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,408 +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.tx;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.transaction.xa.Xid;
-
-import org.jboss.logging.Logger;
-
-/**
- * 
- * A JMS Server local transaction
- * 
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @author <a href="mailto:ovidiu at jboss.com">Ovidiu Feodorov</a>
- * 
- * @version $Revision 1.1$
- *
- * $Id$
- */
-public class Transaction
-{
-   // Constants -----------------------------------------------------
-
-   private static final Logger log = Logger.getLogger(Transaction.class);
-
-   // Attributes ----------------------------------------------------
-   
-   private boolean trace = log.isTraceEnabled();
-     
-   private long id;
-   
-   private int state;
-   
-   private Xid xid;
-   
-   private List callbacks;
-   
-   private Map callbackMap;
-   
-   private boolean recoveredFromStorage;
-         
-   /**
-    * If this is a XA transaction, when a commit is executed the transaction has to be removed from the transaction repository.
-    * This reference will guarantee the reference back to the repository where the transaction was created
-    *
-   */
-   protected TransactionRepository repository;
-   
-   //A special first callback that is ensured to be executed first
-   protected TxCallback firstCallback;
-   
-   // Static --------------------------------------------------------
-   
-   public static final int STATE_ACTIVE = 0;
-   
-   public static final int STATE_PREPARED = 1;
-   
-   public static final int STATE_COMMITTED = 2;
-   
-   public static final int STATE_ROLLEDBACK = 3;
-
-   public static final int STATE_ROLLBACK_ONLY = 4;
-
-   public static String stateToString(int state)
-   {
-      if (state == STATE_ACTIVE)
-      {
-         return "ACTIVE";
-      }
-      else if (state == STATE_PREPARED)
-      {
-         return "PREPARED";
-      }
-      else if (state == STATE_COMMITTED)
-      {
-         return "COMMITTED";
-      }
-      else if (state == STATE_ROLLEDBACK)
-      {
-         return "ROLLEDBACK";
-      }
-      else if (state == STATE_ROLLBACK_ONLY)
-      {
-         return "ROLLBACK_ONLY";
-      }
-      else
-      {
-         return "UNKNOWN";
-      }
-   }
-
-   // Constructors --------------------------------------------------
-   
-   Transaction(long id)
-   {
-      this.id = id;
-      state = STATE_ACTIVE;
-      callbacks = new ArrayList();
-      callbackMap = new HashMap();
-   }
-   
-   Transaction(long id, Xid xid, TransactionRepository tr)
-   {
-      this(id);
-      this.xid = xid;
-      this.repository = tr;
-   }
-   
-   // Public --------------------------------------------------------
-   
-   public int getState()
-   {
-      return state;
-   }      
-   
-   public Xid getXid()
-   {
-      return xid;
-   }
-
-   public void addCallback(TxCallback callback, Object key)
-   {            
-      callbacks.add(callback);
-      
-      callbackMap.put(key, callback);
-   } 
-   
-   public void addFirstCallback(TxCallback callback, Object key)
-   {            
-      if (firstCallback != null)
-      {
-         throw new IllegalStateException("There is already a first callback");
-      }
-      
-      this.firstCallback = callback;
-      
-      callbackMap.put(key, callback);
-   }
-   
-   public TxCallback getCallback(Object key)
-   {
-      return (TxCallback)callbackMap.get(key);
-   }
-      
-   public synchronized void commit() throws Exception
-   {
-      if (state == STATE_ROLLBACK_ONLY)
-      {
-         throw new TransactionException("Transaction marked rollback only, cannot commit");
-      }
-      if (state == STATE_COMMITTED)
-      {
-         throw new TransactionException("Transaction already committed, cannot commit");
-      }
-      if (state == STATE_ROLLEDBACK)
-      {
-         throw new TransactionException("Transaction already rolled back, cannot commit");
-      }
-      
-      if (recoveredFromStorage)
-      {
-         //Commit can come in for an in doubt tx that has been recovered from storage
-         //but for which recover() has not yet been called
-         //therefore we might need to load it's state
-         loadState();
-      }
-
-      if (trace) { log.trace(this + " executing before commit hooks"); }
-       
-      boolean onePhase = state != STATE_PREPARED;
-      
-      if (firstCallback != null)
-      {
-         firstCallback.beforeCommit(onePhase);
-      }
-      
-      Iterator iter = callbacks.iterator();
-      
-      while (iter.hasNext())
-      {
-         TxCallback callback = (TxCallback)iter.next();
-         
-         callback.beforeCommit(onePhase);
-      }
-      
-      state = STATE_COMMITTED;
-      
-      if (trace) { log.trace(this + " committed"); }
-      
-      iter = callbacks.iterator();
-      
-      if (trace) { log.trace(this + " executing after commit hooks"); }
-      
-      if (firstCallback != null)
-      {         
-         firstCallback.afterCommit(onePhase);
-      }
-      
-      while (iter.hasNext())
-      {
-         TxCallback callback = (TxCallback)iter.next();
-         
-         callback.afterCommit(onePhase);
-      }
-          
-      callbacks = null;
-      
-      callbackMap = null;      
-      
-      firstCallback = null;
-      
-      if (repository != null)
-      {
-         repository.deleteTransaction(this);
-      }
-            
-      if (trace) { log.trace(this + " commit process complete"); }
-   }
-   
-   public synchronized void prepare() throws Exception
-   {
-      if (state != STATE_ACTIVE)
-      {
-         throw new TransactionException("Transaction not active, cannot prepare");
-      }
-      
-      if (trace) { log.trace(this + " executing before prepare hooks"); }
-      
-      if (firstCallback != null)
-      {
-         firstCallback.beforePrepare();
-      }
-      
-      Iterator iter = callbacks.iterator();
-      
-      while (iter.hasNext())
-      {
-         TxCallback callback = (TxCallback)iter.next();
-         
-         callback.beforePrepare();
-      }
-      
-      state = STATE_PREPARED;
-      
-      if (trace) { log.trace(this + " prepared"); }
-      
-      if (firstCallback != null)
-      {
-         firstCallback.afterPrepare();
-      }
-      
-      iter = callbacks.iterator();
-      
-      if (trace) { log.trace(this + " executing after prepare hooks"); }
-      
-      while (iter.hasNext())
-      {
-         TxCallback callback = (TxCallback)iter.next();
-         
-         callback.afterPrepare();
-      }            
-      
-      if (trace) { log.trace(this + " prepare process complete"); }
-   }
-   
-   public synchronized void rollback() throws Exception
-   {
-      if (state == STATE_COMMITTED)
-      {
-         throw new TransactionException("Transaction already committed, cannot rollback");
-      }
-      if (state == STATE_ROLLEDBACK)
-      {
-         throw new TransactionException("Transaction already rolled back, cannot rollback");
-      }
-      
-      if (recoveredFromStorage)
-      {
-         //Commit can come in for an in doubt tx that has been recovered from storage
-         //but for which recover() has not yet been called
-         //therefore we might need to load it's state
-         loadState();
-      }
-      
-      if (trace) { log.trace(this + " executing before rollback hooks"); }
-      
-      boolean onePhase = state != STATE_PREPARED;
-      
-      if (firstCallback != null)
-      {
-         firstCallback.beforeRollback(onePhase);
-      }
-
-      for(Iterator i = callbacks.iterator(); i.hasNext(); )
-      {
-         TxCallback callback = (TxCallback)i.next();
-         callback.beforeRollback(onePhase);
-      }
-      
-      state = STATE_ROLLEDBACK;
-      
-      if (trace) { log.trace(this + " rolled back"); }
-
-      if (trace) { log.trace(this + " executing after rollback hooks"); }
-
-      if (firstCallback != null)
-      {
-         firstCallback.afterRollback(onePhase);
-      }
-      
-      for(Iterator i = callbacks.iterator(); i.hasNext();)
-      {
-         TxCallback callback = (TxCallback)i.next();
-         callback.afterRollback(onePhase);
-      }            
-      
-      callbacks = null;
-      callbackMap = null;
-      
-      if (repository != null)
-      {
-         repository.deleteTransaction(this);
-      }
-      
-      if (trace) { log.trace(this + " rollback process complete"); }
-   }
-
-   public void loadState() throws Exception
-   {
-      repository.handleReferences(this);
-      
-      repository.handleAcks(this);
-      
-      recoveredFromStorage = false;
-   }
-   
-   public synchronized void setRollbackOnly() throws Exception
-   {
-      if (trace) { log.trace("setting ROLLBACK_ONLY on " + this); }
-
-      state = STATE_ROLLBACK_ONLY;
-   }
-   
-   public long getId()
-   {
-      return id;
-   }
-   
-   public boolean isRecoveredFromStorage()
-   {
-      return this.recoveredFromStorage;
-   }
-   
-   public void setRecoveredFromStorage(boolean recoveredFromStorage)
-   {
-      this.recoveredFromStorage = recoveredFromStorage;
-   }
-   
-   public void setState(int state)
-   {
-      this.state = state;
-   }
-      
-   public String toString()
-   {
-      StringBuffer sb = new StringBuffer("TX(");
-      sb.append(id);
-      sb.append("):");
-      sb.append(stateToString(state));
-      return sb.toString();
-   }
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------
-   
-}
-
-

Copied: trunk/src/main/org/jboss/messaging/core/impl/tx/Transaction.java (from rev 2795, trunk/src/main/org/jboss/messaging/core/tx/Transaction.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/tx/Transaction.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/tx/Transaction.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,408 @@
+/*
+  * 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.impl.tx;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.transaction.xa.Xid;
+
+import org.jboss.logging.Logger;
+
+/**
+ * 
+ * A JMS Server local transaction
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:ovidiu at jboss.com">Ovidiu Feodorov</a>
+ * 
+ * @version $Revision 1.1$
+ *
+ * $Id$
+ */
+public class Transaction
+{
+   // Constants -----------------------------------------------------
+
+   private static final Logger log = Logger.getLogger(Transaction.class);
+
+   // Attributes ----------------------------------------------------
+   
+   private boolean trace = log.isTraceEnabled();
+     
+   private long id;
+   
+   private int state;
+   
+   private Xid xid;
+   
+   private List callbacks;
+   
+   private Map callbackMap;
+   
+   private boolean recoveredFromStorage;
+         
+   /**
+    * If this is a XA transaction, when a commit is executed the transaction has to be removed from the transaction repository.
+    * This reference will guarantee the reference back to the repository where the transaction was created
+    *
+   */
+   protected TransactionRepository repository;
+   
+   //A special first callback that is ensured to be executed first
+   protected TxCallback firstCallback;
+   
+   // Static --------------------------------------------------------
+   
+   public static final int STATE_ACTIVE = 0;
+   
+   public static final int STATE_PREPARED = 1;
+   
+   public static final int STATE_COMMITTED = 2;
+   
+   public static final int STATE_ROLLEDBACK = 3;
+
+   public static final int STATE_ROLLBACK_ONLY = 4;
+
+   public static String stateToString(int state)
+   {
+      if (state == STATE_ACTIVE)
+      {
+         return "ACTIVE";
+      }
+      else if (state == STATE_PREPARED)
+      {
+         return "PREPARED";
+      }
+      else if (state == STATE_COMMITTED)
+      {
+         return "COMMITTED";
+      }
+      else if (state == STATE_ROLLEDBACK)
+      {
+         return "ROLLEDBACK";
+      }
+      else if (state == STATE_ROLLBACK_ONLY)
+      {
+         return "ROLLBACK_ONLY";
+      }
+      else
+      {
+         return "UNKNOWN";
+      }
+   }
+
+   // Constructors --------------------------------------------------
+   
+   Transaction(long id)
+   {
+      this.id = id;
+      state = STATE_ACTIVE;
+      callbacks = new ArrayList();
+      callbackMap = new HashMap();
+   }
+   
+   Transaction(long id, Xid xid, TransactionRepository tr)
+   {
+      this(id);
+      this.xid = xid;
+      this.repository = tr;
+   }
+   
+   // Public --------------------------------------------------------
+   
+   public int getState()
+   {
+      return state;
+   }      
+   
+   public Xid getXid()
+   {
+      return xid;
+   }
+
+   public void addCallback(TxCallback callback, Object key)
+   {            
+      callbacks.add(callback);
+      
+      callbackMap.put(key, callback);
+   } 
+   
+   public void addFirstCallback(TxCallback callback, Object key)
+   {            
+      if (firstCallback != null)
+      {
+         throw new IllegalStateException("There is already a first callback");
+      }
+      
+      this.firstCallback = callback;
+      
+      callbackMap.put(key, callback);
+   }
+   
+   public TxCallback getCallback(Object key)
+   {
+      return (TxCallback)callbackMap.get(key);
+   }
+      
+   public synchronized void commit() throws Exception
+   {
+      if (state == STATE_ROLLBACK_ONLY)
+      {
+         throw new TransactionException("Transaction marked rollback only, cannot commit");
+      }
+      if (state == STATE_COMMITTED)
+      {
+         throw new TransactionException("Transaction already committed, cannot commit");
+      }
+      if (state == STATE_ROLLEDBACK)
+      {
+         throw new TransactionException("Transaction already rolled back, cannot commit");
+      }
+      
+      if (recoveredFromStorage)
+      {
+         //Commit can come in for an in doubt tx that has been recovered from storage
+         //but for which recover() has not yet been called
+         //therefore we might need to load it's state
+         loadState();
+      }
+
+      if (trace) { log.trace(this + " executing before commit hooks"); }
+       
+      boolean onePhase = state != STATE_PREPARED;
+      
+      if (firstCallback != null)
+      {
+         firstCallback.beforeCommit(onePhase);
+      }
+      
+      Iterator iter = callbacks.iterator();
+      
+      while (iter.hasNext())
+      {
+         TxCallback callback = (TxCallback)iter.next();
+         
+         callback.beforeCommit(onePhase);
+      }
+      
+      state = STATE_COMMITTED;
+      
+      if (trace) { log.trace(this + " committed"); }
+      
+      iter = callbacks.iterator();
+      
+      if (trace) { log.trace(this + " executing after commit hooks"); }
+      
+      if (firstCallback != null)
+      {         
+         firstCallback.afterCommit(onePhase);
+      }
+      
+      while (iter.hasNext())
+      {
+         TxCallback callback = (TxCallback)iter.next();
+         
+         callback.afterCommit(onePhase);
+      }
+          
+      callbacks = null;
+      
+      callbackMap = null;      
+      
+      firstCallback = null;
+      
+      if (repository != null)
+      {
+         repository.deleteTransaction(this);
+      }
+            
+      if (trace) { log.trace(this + " commit process complete"); }
+   }
+   
+   public synchronized void prepare() throws Exception
+   {
+      if (state != STATE_ACTIVE)
+      {
+         throw new TransactionException("Transaction not active, cannot prepare");
+      }
+      
+      if (trace) { log.trace(this + " executing before prepare hooks"); }
+      
+      if (firstCallback != null)
+      {
+         firstCallback.beforePrepare();
+      }
+      
+      Iterator iter = callbacks.iterator();
+      
+      while (iter.hasNext())
+      {
+         TxCallback callback = (TxCallback)iter.next();
+         
+         callback.beforePrepare();
+      }
+      
+      state = STATE_PREPARED;
+      
+      if (trace) { log.trace(this + " prepared"); }
+      
+      if (firstCallback != null)
+      {
+         firstCallback.afterPrepare();
+      }
+      
+      iter = callbacks.iterator();
+      
+      if (trace) { log.trace(this + " executing after prepare hooks"); }
+      
+      while (iter.hasNext())
+      {
+         TxCallback callback = (TxCallback)iter.next();
+         
+         callback.afterPrepare();
+      }            
+      
+      if (trace) { log.trace(this + " prepare process complete"); }
+   }
+   
+   public synchronized void rollback() throws Exception
+   {
+      if (state == STATE_COMMITTED)
+      {
+         throw new TransactionException("Transaction already committed, cannot rollback");
+      }
+      if (state == STATE_ROLLEDBACK)
+      {
+         throw new TransactionException("Transaction already rolled back, cannot rollback");
+      }
+      
+      if (recoveredFromStorage)
+      {
+         //Commit can come in for an in doubt tx that has been recovered from storage
+         //but for which recover() has not yet been called
+         //therefore we might need to load it's state
+         loadState();
+      }
+      
+      if (trace) { log.trace(this + " executing before rollback hooks"); }
+      
+      boolean onePhase = state != STATE_PREPARED;
+      
+      if (firstCallback != null)
+      {
+         firstCallback.beforeRollback(onePhase);
+      }
+
+      for(Iterator i = callbacks.iterator(); i.hasNext(); )
+      {
+         TxCallback callback = (TxCallback)i.next();
+         callback.beforeRollback(onePhase);
+      }
+      
+      state = STATE_ROLLEDBACK;
+      
+      if (trace) { log.trace(this + " rolled back"); }
+
+      if (trace) { log.trace(this + " executing after rollback hooks"); }
+
+      if (firstCallback != null)
+      {
+         firstCallback.afterRollback(onePhase);
+      }
+      
+      for(Iterator i = callbacks.iterator(); i.hasNext();)
+      {
+         TxCallback callback = (TxCallback)i.next();
+         callback.afterRollback(onePhase);
+      }            
+      
+      callbacks = null;
+      callbackMap = null;
+      
+      if (repository != null)
+      {
+         repository.deleteTransaction(this);
+      }
+      
+      if (trace) { log.trace(this + " rollback process complete"); }
+   }
+
+   public void loadState() throws Exception
+   {
+      repository.handleReferences(this);
+      
+      repository.handleAcks(this);
+      
+      recoveredFromStorage = false;
+   }
+   
+   public synchronized void setRollbackOnly() throws Exception
+   {
+      if (trace) { log.trace("setting ROLLBACK_ONLY on " + this); }
+
+      state = STATE_ROLLBACK_ONLY;
+   }
+   
+   public long getId()
+   {
+      return id;
+   }
+   
+   public boolean isRecoveredFromStorage()
+   {
+      return this.recoveredFromStorage;
+   }
+   
+   public void setRecoveredFromStorage(boolean recoveredFromStorage)
+   {
+      this.recoveredFromStorage = recoveredFromStorage;
+   }
+   
+   public void setState(int state)
+   {
+      this.state = state;
+   }
+      
+   public String toString()
+   {
+      StringBuffer sb = new StringBuffer("TX(");
+      sb.append(id);
+      sb.append("):");
+      sb.append(stateToString(state));
+      return sb.toString();
+   }
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------
+   
+}
+
+

Deleted: trunk/src/main/org/jboss/messaging/core/impl/tx/TransactionException.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/tx/TransactionException.java	2007-06-13 18:15:18 UTC (rev 2781)
+++ trunk/src/main/org/jboss/messaging/core/impl/tx/TransactionException.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,43 +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.tx;
-
-/**
- * 
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- *
- * @version <tt>$Revision$</tt>
- */
-public class TransactionException extends Exception
-{
-   private static final long serialVersionUID = 2461082362655828741L;
-
-   public TransactionException(String msg)
-   {
-      super(msg);
-   }
-   
-   public TransactionException(String msg, Throwable t)
-   {
-      super(msg, t);
-   }
-}

Copied: trunk/src/main/org/jboss/messaging/core/impl/tx/TransactionException.java (from rev 2795, trunk/src/main/org/jboss/messaging/core/tx/TransactionException.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/tx/TransactionException.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/tx/TransactionException.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.impl.tx;
+
+/**
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ *
+ * @version <tt>$Revision$</tt>
+ */
+public class TransactionException extends Exception
+{
+   private static final long serialVersionUID = 2461082362655828741L;
+
+   public TransactionException(String msg)
+   {
+      super(msg);
+   }
+   
+   public TransactionException(String msg, Throwable t)
+   {
+      super(msg, t);
+   }
+}

Deleted: trunk/src/main/org/jboss/messaging/core/impl/tx/TransactionRepository.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/tx/TransactionRepository.java	2007-06-13 18:15:18 UTC (rev 2781)
+++ trunk/src/main/org/jboss/messaging/core/impl/tx/TransactionRepository.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,536 +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.tx;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.transaction.xa.Xid;
-
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.Queue;
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.IDManager;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.plugin.contract.PostOffice;
-import org.jboss.messaging.core.plugin.postoffice.Binding;
-
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
-
-/**
- * This class maintains JMS Server local transactions.
- * 
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @author <a href="mailto:Konda.Madhu at uk.mizuho-sc.com">Madhu Konda</a>
- * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
- *
- * @version $Revision 1.1 $
- *
- * $Id$
- */
-public class TransactionRepository implements MessagingComponent
-{
-   // Constants -----------------------------------------------------
-
-   private static final Logger log = Logger.getLogger(TransactionRepository.class);
-
-   // Attributes ----------------------------------------------------
-   
-   private boolean trace = log.isTraceEnabled();
-   
-   private Map globalToLocalMap;     
-   
-   private PersistenceManager persistenceManager;
-
-   protected MessageStore messageStore;
-
-   private IDManager idManager;
-   
-   private PostOffice postOffice;
-   
-   // Static --------------------------------------------------------
-   
-   // Constructors --------------------------------------------------
-   
-   public TransactionRepository(PersistenceManager persistenceManager, MessageStore store, IDManager idManager)
-   {
-      this.persistenceManager = persistenceManager;
-      
-      this.messageStore = store;
-      
-      this.idManager = idManager;
-      
-      globalToLocalMap = new ConcurrentHashMap();        
-   }
-   
-   // Injection ----------------------------------------
-   
-   //Unfortunately we have to do this for now, since PostOffice is not started until after this is constructed
-   //We will sort out dependencies properly when we go to the micro container
-   public void injectPostOffice(PostOffice po)
-   {
-      postOffice = po;
-   }
-   
-
-   // MessagingComponent implementation --------------------------------
-   
-   public void start() throws Exception
-   {
-      //NOOP
-   }
-   
-   // Public --------------------------------------------------------
-      
-   public void stop() throws Exception
-   {
-      //NOOP
-   }
-   
-   // Public --------------------------------------------------------   
-
-   /**
-    * Attempts to recover existing prepared transactions by redelivering unhandled messages and acknowledgements
-    * on the appropriate channels.
-    *
-    * @return  List of Xid instances
-    */
-   public synchronized List recoverPreparedTransactions()
-   {
-      if (trace) { log.trace(this + " recoverPreparedTransactions()"); }
-      
-      ArrayList prepared = new ArrayList();
-
-      Iterator iter = globalToLocalMap.values().iterator();
-      
-      while (iter.hasNext())
-      {
-         Transaction tx = (Transaction) iter.next();
-         
-         if (tx.getXid() != null && tx.getState() == Transaction.STATE_PREPARED)
-         {
-            try
-            {
-               if (trace) log.trace("Loading and handling refs and acks to the Tx "+tx);
-
-               //The transaction might have been created, prepared, without the server crashing
-               //in which case the tx will already have the references and acks in them
-               //in this case we DO NOT want to replay them again, since they will end up in the transaction state
-               //twice
-               //In other words we only want to replay acks and sends if this tx was recovered from the db
-               if (tx.isRecoveredFromStorage())
-               {
-                  tx.loadState();
-               }
-            }
-            catch (Exception e)
-            {
-               log.warn("Failed to replay transaction (XID: " + tx.getXid() + ", LocalID: " + tx.getId() + ") during recovery.", e);
-            }
-
-            prepared.add(tx.getXid());
-         }
-      }
-      
-      if (trace) { log.trace("Returning " + prepared.size() + " transactions"); }
-
-      return prepared;
-   }
-
-   /*
-    * Load any prepared transactions into the repository so they can be
-    * recovered
-    */
-   public void loadPreparedTransactions() throws Exception
-   {
-      if (trace) log.trace("load prepared transactions...");
-
-      List prepared = null;
-
-      prepared = persistenceManager.retrievePreparedTransactions();
-
-      if (trace) log.trace ("found " + prepared.size() + " transactions in prepared state");
-
-      if (prepared != null)
-      {
-         Iterator iter = prepared.iterator();
-
-         while (iter.hasNext())
-         {
-            PreparedTxInfo txInfo = (PreparedTxInfo) iter.next();
-
-            //This method may be called more than once - e.g. when failover occurs so we don't want to add the
-            //prepared tx if it is already in memory
-            
-            if (!globalToLocalMap.containsKey(txInfo.getXid()))
-            {
-               Transaction tx = createTransaction(txInfo);
-               
-               tx.setState(Transaction.STATE_PREPARED);
-               
-               tx.setRecoveredFromStorage(true);
-               
-               if (trace) log.trace("reinstating TX(XID: " + txInfo.getXid() + ", LocalId " + txInfo.getTxId() +")");
-               
-            }  
-            else
-            {
-               if (trace) log.trace("Not adding to map since it's already in map");
-            }
-         }
-      }     
-   }
-   
-   public List getPreparedTransactions()
-   {
-      return new ArrayList(globalToLocalMap.keySet());
-   }
-
-   public Transaction getPreparedTx(Xid xid) throws Exception
-   {            
-      Transaction tx = (Transaction)globalToLocalMap.get(xid);
-
-      if (tx == null)
-      {
-         throw new TransactionException("Cannot find local tx for xid:" + xid);
-      }
-      if (tx.getState() != Transaction.STATE_PREPARED)
-      {
-         throw new TransactionException("Transaction with xid " + xid + " is not in prepared state");
-      }
-      return tx;
-   }
-   
-   public void deleteTransaction(Transaction transaction) throws Exception
-   {
-	   final Xid id = transaction.getXid();
-	   final int state = transaction.getState();
-	   
-	   if (id == null)
-	   {
-		   throw new IllegalArgumentException("DeleteTransaction was called for non XA transaction");
-	   }
-
-	   if (state != Transaction.STATE_COMMITTED && state != Transaction.STATE_ROLLEDBACK)
-	   {
-		   throw new TransactionException("Transaction with xid " + id + " can't be removed as it's not yet commited or rolledback: (Current state is " + Transaction.stateToString(state));
-	   }
-      
-	   globalToLocalMap.remove(id);	   
-   }
-   
-   public Transaction createTransaction(Xid xid) throws Exception
-   {
-      if (globalToLocalMap.containsKey(xid))
-      {
-         throw new TransactionException("There is already a local tx for global tx " + xid);
-      }
-      Transaction tx = new Transaction(idManager.getID(), xid, this);
-      
-      if (trace) { log.trace("created transaction " + tx); }
-      
-      globalToLocalMap.put(xid, tx);
-      
-      return tx;
-   }
-   
-   public Transaction createTransaction() throws Exception
-   {
-      Transaction tx = new Transaction(idManager.getID());
-      
-      if (trace) { log.trace("created transaction " + tx); }
-
-      return tx;
-   }
-
-   public boolean removeTransaction(Xid xid)
-   {
-      return globalToLocalMap.remove(xid) != null;
-   }
-   
-   /** To be used only by testcases */
-   public int getNumberOfRegisteredTransactions()
-   {
-	  return this.globalToLocalMap.size();   
-   }
-   
-   
-   
-   // Package protected ---------------------------------------------
-   
-   /**
-    * Load the references and invoke the channel to handle those refs
-    */
-   void handleReferences(Transaction tx) throws Exception
-   {
-      if (trace) log.trace("Handle references for TX(XID: " + tx.getXid() + ", LocalID: " + tx.getId()+ "):");
-
-      long txId = tx.getId();
-
-      List pairs = persistenceManager.getMessageChannelPairRefsForTx(txId);
-
-      if (trace) log.trace("Found " + pairs.size() + " unhandled references.");
-
-      for (Iterator iter = pairs.iterator(); iter.hasNext();)
-      {
-         PersistenceManager.MessageChannelPair pair = (PersistenceManager.MessageChannelPair)iter.next();
-         
-         Message msg = pair.getMessage();
-         
-         long channelID = pair.getChannelId();
-         
-         MessageReference ref = null;
-         
-         try
-         {
-            ref = messageStore.reference(msg);         
-
-            //Need to get the post office reference lazily, cannot pass into constructor
-            Binding binding = postOffice.getBindingforChannelId(channelID);
-            
-            if (binding == null)
-            {
-               throw new IllegalStateException("Cannot find binding for channel id " + channelID);
-            }
-            
-            Queue queue = binding.getQueue();
-                        
-            if (trace) log.trace("Destination for message[ID=" + ref.getMessage().getMessageID() + "] is: " + queue);
-   
-            // The actual jmx queue may not have been deployed yet, so we need to activate it if so, 
-            // or the handle will have no effect
-                        
-            boolean deactivate = false;
-
-            if (!queue.isActive())
-            {
-            	queue.activate();
-
-            	deactivate = true;
-            }
-
-            queue.handle(null, ref, tx);
-
-            if (deactivate)
-            {
-            	queue.deactivate();
-            }
-         }
-         finally
-         {
-            if (ref != null)
-            {
-               //Need to release reference
-               ref.releaseMemoryReference();
-            }
-         }
-      }
-   }
-
-   /**
-    * Load the acks and acknowledge them
-    */
-   void handleAcks(Transaction tx) throws Exception
-   {
-      long txId = tx.getId();
-      
-      List pairs = persistenceManager.getMessageChannelPairAcksForTx(txId);
-
-      if (trace) log.trace("Found " + pairs.size() + " unhandled acks.");
-      
-      List dels = new ArrayList();
-
-      for (Iterator iter = pairs.iterator(); iter.hasNext();)
-      {
-         PersistenceManager.MessageChannelPair pair = (PersistenceManager.MessageChannelPair)iter.next();
-         
-         Message msg = pair.getMessage();
-         
-         long channelID = pair.getChannelId();
-         
-         MessageReference ref = null;
-         
-         try
-         {
-            ref = messageStore.reference(msg);         
-
-            // Need to get the post office reference lazily, cannot pass into constructor
-            Binding binding = postOffice.getBindingforChannelId(channelID);
-            
-            if (binding == null)
-            {
-               throw new IllegalStateException("Cannot find binding for channel id " + channelID);
-            }
-            
-            Queue queue = binding.getQueue();
-   
-            if (trace) log.trace("Destination for message[ID=" + ref.getMessage().getMessageID() + "] is: " + queue);
-   
-            //Create a new delivery - note that it must have a delivery observer otherwise acknowledge will fail
-            Delivery del = new SimpleDelivery(queue, ref);
-
-            if (trace) log.trace("Acknowledging..");
-
-            try
-            {
-            	// The actual jmx queue may not have been deployed yet, so we need to activate it if so, 
-               // or the acknowledge will have no effect
-                           
-               boolean deactivate = false;
-
-               if (!queue.isActive())
-               {
-               	queue.activate();
-
-               	deactivate = true;
-               }
-
-               del.acknowledge(tx);
-
-               if (deactivate)
-               {
-               	queue.deactivate();
-               }
-            }
-            catch (Throwable t)
-            {
-               log.error("Failed to acknowledge " + del + " during recovery", t);
-            }
-            
-            dels.add(del);            
-         }
-         finally
-         {
-            if (ref != null)
-            {
-               //Need to release reference
-               ref.releaseMemoryReference();
-            }
-         }
-      }
-      
-      if (!dels.isEmpty())
-      {
-         //Add a callback so these dels get cancelled on rollback
-         tx.addCallback(new CancelCallback(dels), this);
-      }
-      
-   }
-   
-   // Protected -----------------------------------------------------         
-   
-   // Private -------------------------------------------------------
-
-	         
-      
-	/**
-	 * Creates a prepared transaction
-	 *
-	 * @param txInfo
-	 * @return
-	 * @throws Exception
-	 */
-	private Transaction createTransaction(PreparedTxInfo txInfo) throws Exception
-   {
-		if (globalToLocalMap.containsKey(txInfo.getXid()))
-      {
-			throw new TransactionException(
-					"There is already a local tx for global tx "	+ txInfo.getXid());
-		}
-
-		// Resurrected tx
-		Transaction tx = new Transaction(txInfo.getTxId(), txInfo.getXid(), this);
-
-		if (trace) {
-			log.trace("created transaction " + tx);
-		}
-
-		globalToLocalMap.put(txInfo.getXid(), tx);
-
-		return tx;
-	}
-
-   // Inner classes -------------------------------------------------
-   
-   private class CancelCallback implements TxCallback
-   {
-      private List toCancel;
-      
-      private CancelCallback(List toCancel)
-      {
-         this.toCancel = toCancel;
-      }
-
-      public void afterCommit(boolean onePhase) throws Exception
-      {
-      }
-
-      public void afterPrepare() throws Exception
-      {
-      }
-
-      public void afterRollback(boolean onePhase) throws Exception
-      {
-         //On rollback we need to cancel the ref back into the channel
-         //We only need to do this if the tx was reloaded since otherwise the
-         //cancel will come from the SCE
-         
-         //Need to cancel in reverse
-         
-         for (int i = toCancel.size() - 1; i >= 0; i--)
-         {                     
-            Delivery del = (Delivery)toCancel.get(i);
-            
-            try
-            {
-               del.cancel();
-            }
-            catch (Throwable t)
-            {
-               log.error("Failed to cancel delivery", t);
-               throw new TransactionException(t.getMessage(), t);
-            }
-         }
-      }
-
-      public void beforeCommit(boolean onePhase) throws Exception
-      {
-      }
-
-      public void beforePrepare() throws Exception
-      {
-      }
-
-      public void beforeRollback(boolean onePhase) throws Exception
-      {
-      }
-      
-   }
-   
-}
\ No newline at end of file

Copied: trunk/src/main/org/jboss/messaging/core/impl/tx/TransactionRepository.java (from rev 2795, trunk/src/main/org/jboss/messaging/core/tx/TransactionRepository.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/tx/TransactionRepository.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/tx/TransactionRepository.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,534 @@
+/*
+  * 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.impl.tx;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.transaction.xa.Xid;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.contract.Binding;
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.MessagingComponent;
+import org.jboss.messaging.core.contract.PersistenceManager;
+import org.jboss.messaging.core.contract.PostOffice;
+import org.jboss.messaging.core.contract.Queue;
+import org.jboss.messaging.core.impl.IDManager;
+import org.jboss.messaging.core.impl.SimpleDelivery;
+
+import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
+
+/**
+ * This class maintains JMS Server local transactions.
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:Konda.Madhu at uk.mizuho-sc.com">Madhu Konda</a>
+ * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
+ *
+ * @version $Revision 1.1 $
+ *
+ * $Id$
+ */
+public class TransactionRepository implements MessagingComponent
+{
+   // Constants -----------------------------------------------------
+
+   private static final Logger log = Logger.getLogger(TransactionRepository.class);
+
+   // Attributes ----------------------------------------------------
+   
+   private boolean trace = log.isTraceEnabled();
+   
+   private Map globalToLocalMap;     
+   
+   private PersistenceManager persistenceManager;
+
+   protected MessageStore messageStore;
+
+   private IDManager idManager;
+   
+   private PostOffice postOffice;
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   public TransactionRepository(PersistenceManager persistenceManager, MessageStore store, IDManager idManager)
+   {
+      this.persistenceManager = persistenceManager;
+      
+      this.messageStore = store;
+      
+      this.idManager = idManager;
+      
+      globalToLocalMap = new ConcurrentHashMap();        
+   }
+   
+   // Injection ----------------------------------------
+   
+   //Unfortunately we have to do this for now, since PostOffice is not started until after this is constructed
+   //We will sort out dependencies properly when we go to the micro container
+   public void injectPostOffice(PostOffice po)
+   {
+      postOffice = po;
+   }
+   
+
+   // MessagingComponent implementation --------------------------------
+   
+   public void start() throws Exception
+   {
+      //NOOP
+   }
+   
+   // Public --------------------------------------------------------
+      
+   public void stop() throws Exception
+   {
+      //NOOP
+   }
+   
+   // Public --------------------------------------------------------   
+
+   /**
+    * Attempts to recover existing prepared transactions by redelivering unhandled messages and acknowledgements
+    * on the appropriate channels.
+    *
+    * @return  List of Xid instances
+    */
+   public synchronized List recoverPreparedTransactions()
+   {
+      if (trace) { log.trace(this + " recoverPreparedTransactions()"); }
+      
+      ArrayList prepared = new ArrayList();
+
+      Iterator iter = globalToLocalMap.values().iterator();
+      
+      while (iter.hasNext())
+      {
+         Transaction tx = (Transaction) iter.next();
+         
+         if (tx.getXid() != null && tx.getState() == Transaction.STATE_PREPARED)
+         {
+            try
+            {
+               if (trace) log.trace("Loading and handling refs and acks to the Tx "+tx);
+
+               //The transaction might have been created, prepared, without the server crashing
+               //in which case the tx will already have the references and acks in them
+               //in this case we DO NOT want to replay them again, since they will end up in the transaction state
+               //twice
+               //In other words we only want to replay acks and sends if this tx was recovered from the db
+               if (tx.isRecoveredFromStorage())
+               {
+                  tx.loadState();
+               }
+            }
+            catch (Exception e)
+            {
+               log.warn("Failed to replay transaction (XID: " + tx.getXid() + ", LocalID: " + tx.getId() + ") during recovery.", e);
+            }
+
+            prepared.add(tx.getXid());
+         }
+      }
+      
+      if (trace) { log.trace("Returning " + prepared.size() + " transactions"); }
+
+      return prepared;
+   }
+
+   /*
+    * Load any prepared transactions into the repository so they can be
+    * recovered
+    */
+   public void loadPreparedTransactions() throws Exception
+   {
+      if (trace) log.trace("load prepared transactions...");
+
+      List prepared = null;
+
+      prepared = persistenceManager.retrievePreparedTransactions();
+
+      if (trace) log.trace ("found " + prepared.size() + " transactions in prepared state");
+
+      if (prepared != null)
+      {
+         Iterator iter = prepared.iterator();
+
+         while (iter.hasNext())
+         {
+            PreparedTxInfo txInfo = (PreparedTxInfo) iter.next();
+
+            //This method may be called more than once - e.g. when failover occurs so we don't want to add the
+            //prepared tx if it is already in memory
+            
+            if (!globalToLocalMap.containsKey(txInfo.getXid()))
+            {
+               Transaction tx = createTransaction(txInfo);
+               
+               tx.setState(Transaction.STATE_PREPARED);
+               
+               tx.setRecoveredFromStorage(true);
+               
+               if (trace) log.trace("reinstating TX(XID: " + txInfo.getXid() + ", LocalId " + txInfo.getTxId() +")");
+               
+            }  
+            else
+            {
+               if (trace) log.trace("Not adding to map since it's already in map");
+            }
+         }
+      }     
+   }
+   
+   public List getPreparedTransactions()
+   {
+      return new ArrayList(globalToLocalMap.keySet());
+   }
+
+   public Transaction getPreparedTx(Xid xid) throws Exception
+   {            
+      Transaction tx = (Transaction)globalToLocalMap.get(xid);
+
+      if (tx == null)
+      {
+         throw new TransactionException("Cannot find local tx for xid:" + xid);
+      }
+      if (tx.getState() != Transaction.STATE_PREPARED)
+      {
+         throw new TransactionException("Transaction with xid " + xid + " is not in prepared state");
+      }
+      return tx;
+   }
+   
+   public void deleteTransaction(Transaction transaction) throws Exception
+   {
+	   final Xid id = transaction.getXid();
+	   final int state = transaction.getState();
+	   
+	   if (id == null)
+	   {
+		   throw new IllegalArgumentException("DeleteTransaction was called for non XA transaction");
+	   }
+
+	   if (state != Transaction.STATE_COMMITTED && state != Transaction.STATE_ROLLEDBACK)
+	   {
+		   throw new TransactionException("Transaction with xid " + id + " can't be removed as it's not yet commited or rolledback: (Current state is " + Transaction.stateToString(state));
+	   }
+      
+	   globalToLocalMap.remove(id);	   
+   }
+   
+   public Transaction createTransaction(Xid xid) throws Exception
+   {
+      if (globalToLocalMap.containsKey(xid))
+      {
+         throw new TransactionException("There is already a local tx for global tx " + xid);
+      }
+      Transaction tx = new Transaction(idManager.getID(), xid, this);
+      
+      if (trace) { log.trace("created transaction " + tx); }
+      
+      globalToLocalMap.put(xid, tx);
+      
+      return tx;
+   }
+   
+   public Transaction createTransaction() throws Exception
+   {
+      Transaction tx = new Transaction(idManager.getID());
+      
+      if (trace) { log.trace("created transaction " + tx); }
+
+      return tx;
+   }
+
+   public boolean removeTransaction(Xid xid)
+   {
+      return globalToLocalMap.remove(xid) != null;
+   }
+   
+   /** To be used only by testcases */
+   public int getNumberOfRegisteredTransactions()
+   {
+	  return this.globalToLocalMap.size();   
+   }
+   
+   
+   
+   // Package protected ---------------------------------------------
+   
+   /**
+    * Load the references and invoke the channel to handle those refs
+    */
+   void handleReferences(Transaction tx) throws Exception
+   {
+      if (trace) log.trace("Handle references for TX(XID: " + tx.getXid() + ", LocalID: " + tx.getId()+ "):");
+
+      long txId = tx.getId();
+
+      List pairs = persistenceManager.getMessageChannelPairRefsForTx(txId);
+
+      if (trace) log.trace("Found " + pairs.size() + " unhandled references.");
+
+      for (Iterator iter = pairs.iterator(); iter.hasNext();)
+      {
+         PersistenceManager.MessageChannelPair pair = (PersistenceManager.MessageChannelPair)iter.next();
+         
+         Message msg = pair.getMessage();
+         
+         long channelID = pair.getChannelId();
+         
+         MessageReference ref = null;
+         
+         try
+         {
+            ref = messageStore.reference(msg);         
+
+            Binding binding = postOffice.getBindingForChannelID(channelID);
+            
+            if (binding == null)
+            {
+               throw new IllegalStateException("Cannot find binding for channel id " + channelID);
+            }
+            
+            Queue queue = binding.queue;
+                        
+            if (trace) log.trace("Destination for message[ID=" + ref.getMessage().getMessageID() + "] is: " + queue);
+   
+            // The actual jmx queue may not have been deployed yet, so we need to activate the core queue if so, 
+            // or the handle will have no effect
+                        
+            boolean deactivate = false;
+
+            if (!queue.isActive())
+            {
+            	queue.activate();
+
+            	deactivate = true;
+            }
+
+            queue.handle(null, ref, tx);
+
+            if (deactivate)
+            {
+            	queue.deactivate();
+            }
+         }
+         finally
+         {
+            if (ref != null)
+            {
+               //Need to release reference
+               ref.releaseMemoryReference();
+            }
+         }
+      }
+   }
+
+   /**
+    * Load the acks and acknowledge them
+    */
+   void handleAcks(Transaction tx) throws Exception
+   {
+      long txId = tx.getId();
+      
+      List pairs = persistenceManager.getMessageChannelPairAcksForTx(txId);
+
+      if (trace) log.trace("Found " + pairs.size() + " unhandled acks.");
+      
+      List dels = new ArrayList();
+
+      for (Iterator iter = pairs.iterator(); iter.hasNext();)
+      {
+         PersistenceManager.MessageChannelPair pair = (PersistenceManager.MessageChannelPair)iter.next();
+         
+         Message msg = pair.getMessage();
+         
+         long channelID = pair.getChannelId();
+         
+         MessageReference ref = null;
+         
+         try
+         {
+            ref = messageStore.reference(msg);         
+
+            Binding binding = postOffice.getBindingForChannelID(channelID);
+            
+            if (binding == null)
+            {
+               throw new IllegalStateException("Cannot find binding for channel id " + channelID);
+            }                       
+   
+            Queue queue = binding.queue;
+            
+            if (trace) log.trace("Destination for message[ID=" + ref.getMessage().getMessageID() + "] is: " + queue);            
+            
+            //Create a new delivery - note that it must have a delivery observer otherwise acknowledge will fail
+            Delivery del = new SimpleDelivery(queue, ref);
+
+            if (trace) log.trace("Acknowledging..");
+
+            try
+            {
+            	// The actual jmx queue may not have been deployed yet, so we need to the core queue if so, 
+               // or the acknowledge will have no effect
+                           
+               boolean deactivate = false;
+
+               if (!queue.isActive())
+               {
+               	queue.activate();
+
+               	deactivate = true;
+               }
+
+               del.acknowledge(tx);
+
+               if (deactivate)
+               {
+               	queue.deactivate();
+               }
+            }
+            catch (Throwable t)
+            {
+               log.error("Failed to acknowledge " + del + " during recovery", t);
+            }
+            
+            dels.add(del);            
+         }
+         finally
+         {
+            if (ref != null)
+            {
+               //Need to release reference
+               ref.releaseMemoryReference();
+            }
+         }
+      }
+      
+      if (!dels.isEmpty())
+      {
+         //Add a callback so these dels get cancelled on rollback
+         tx.addCallback(new CancelCallback(dels), this);
+      }
+      
+   }
+   
+   // Protected -----------------------------------------------------         
+   
+   // Private -------------------------------------------------------
+
+	         
+      
+	/**
+	 * Creates a prepared transaction
+	 *
+	 * @param txInfo
+	 * @return
+	 * @throws Exception
+	 */
+	private Transaction createTransaction(PreparedTxInfo txInfo) throws Exception
+   {
+		if (globalToLocalMap.containsKey(txInfo.getXid()))
+      {
+			throw new TransactionException(
+					"There is already a local tx for global tx "	+ txInfo.getXid());
+		}
+
+		// Resurrected tx
+		Transaction tx = new Transaction(txInfo.getTxId(), txInfo.getXid(), this);
+
+		if (trace) {
+			log.trace("created transaction " + tx);
+		}
+
+		globalToLocalMap.put(txInfo.getXid(), tx);
+
+		return tx;
+	}
+
+   // Inner classes -------------------------------------------------
+   
+   private class CancelCallback implements TxCallback
+   {
+      private List toCancel;
+      
+      private CancelCallback(List toCancel)
+      {
+         this.toCancel = toCancel;
+      }
+
+      public void afterCommit(boolean onePhase) throws Exception
+      {
+      }
+
+      public void afterPrepare() throws Exception
+      {
+      }
+
+      public void afterRollback(boolean onePhase) throws Exception
+      {
+         //On rollback we need to cancel the ref back into the channel
+         //We only need to do this if the tx was reloaded since otherwise the
+         //cancel will come from the SCE
+         
+         //Need to cancel in reverse
+         
+         for (int i = toCancel.size() - 1; i >= 0; i--)
+         {                     
+            Delivery del = (Delivery)toCancel.get(i);
+            
+            try
+            {
+               del.cancel();
+            }
+            catch (Throwable t)
+            {
+               log.error("Failed to cancel delivery", t);
+               throw new TransactionException(t.getMessage(), t);
+            }
+         }
+      }
+
+      public void beforeCommit(boolean onePhase) throws Exception
+      {
+      }
+
+      public void beforePrepare() throws Exception
+      {
+      }
+
+      public void beforeRollback(boolean onePhase) throws Exception
+      {
+      }
+      
+   }
+   
+}
\ No newline at end of file

Deleted: trunk/src/main/org/jboss/messaging/core/impl/tx/TxCallback.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/tx/TxCallback.java	2007-06-13 18:15:18 UTC (rev 2781)
+++ trunk/src/main/org/jboss/messaging/core/impl/tx/TxCallback.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,45 +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.tx;
-
-/**
- * 
- * Callback interface, called at points in transaction lifecycle
- * 
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- *
- * $Id$
- */
-public interface TxCallback
-{
-   void beforePrepare() throws Exception;
-   
-   void beforeCommit(boolean onePhase) throws Exception;
-   
-   void beforeRollback(boolean onePhase) throws Exception;
-   
-   void afterPrepare() throws Exception;
-   
-   void afterCommit(boolean onePhase) throws Exception;
-   
-   void afterRollback(boolean onePhase) throws Exception;
-}

Copied: trunk/src/main/org/jboss/messaging/core/impl/tx/TxCallback.java (from rev 2795, trunk/src/main/org/jboss/messaging/core/tx/TxCallback.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/tx/TxCallback.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/tx/TxCallback.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,45 @@
+/*
+  * 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.impl.tx;
+
+/**
+ * 
+ * Callback interface, called at points in transaction lifecycle
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ *
+ * $Id$
+ */
+public interface TxCallback
+{
+   void beforePrepare() throws Exception;
+   
+   void beforeCommit(boolean onePhase) throws Exception;
+   
+   void beforeRollback(boolean onePhase) throws Exception;
+   
+   void afterPrepare() throws Exception;
+   
+   void afterCommit(boolean onePhase) throws Exception;
+   
+   void afterRollback(boolean onePhase) throws Exception;
+}

Copied: trunk/src/main/org/jboss/messaging/core/jmx/JDBCMBeanSupport.java (from rev 2781, trunk/src/main/org/jboss/messaging/core/plugin/JDBCMBeanSupport.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/jmx/JDBCMBeanSupport.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/jmx/JDBCMBeanSupport.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,181 @@
+/*
+ * 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.jmx;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import javax.management.MBeanServerInvocationHandler;
+import javax.management.ObjectName;
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
+import javax.transaction.TransactionManager;
+
+import org.jboss.messaging.util.ExceptionUtil;
+import org.jboss.system.ServiceMBeanSupport;
+import org.jboss.tm.TransactionManagerServiceMBean;
+
+/**
+ * A JDBCMBeanSupport
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ *
+ */
+public class JDBCMBeanSupport extends ServiceMBeanSupport
+{
+   protected DataSource ds;
+   
+   protected Properties sqlProperties;
+         
+   protected TransactionManager tm;
+      
+   private String dataSourceJNDIName;
+   
+   private boolean createTablesOnStartup = true;
+   
+   private ObjectName tmObjectName;
+     
+   public JDBCMBeanSupport()
+   {
+      sqlProperties = new Properties();
+   }   
+   
+   // 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!");
+         }
+         
+         log.debug(this + " started");
+         
+         tm = getTransactionManagerReference();
+      }
+      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 ----------------------------------------------------------     
+   
+   // Private ----------------------------------------------------------------
+   
+   private TransactionManager getTransactionManagerReference()
+   {
+      // lazy initialization
+      if (tm == null)
+      {
+         TransactionManagerServiceMBean tms =
+            (TransactionManagerServiceMBean)MBeanServerInvocationHandler.
+            newProxyInstance(getServer(), tmObjectName, TransactionManagerServiceMBean.class, false);
+
+         tm = tms.getTransactionManager();
+      }
+
+      return tm;
+   }
+           
+   // Innner classes ---------------------------------------------------------   
+}

Added: trunk/src/main/org/jboss/messaging/core/jmx/JDBCPersistenceManagerService.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/jmx/JDBCPersistenceManagerService.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/jmx/JDBCPersistenceManagerService.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,163 @@
+/*
+ * 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.jmx;
+
+import javax.transaction.TransactionManager;
+
+import org.jboss.messaging.core.contract.MessagingComponent;
+import org.jboss.messaging.core.contract.PersistenceManager;
+import org.jboss.messaging.core.impl.JDBCPersistenceManager;
+import org.jboss.messaging.util.ExceptionUtil;
+
+/**
+ * A JDBCPersistenceManagerService
+ * 
+ * MBean wrapper around a JDBCPersistenceManager
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 2684 $</tt>
+ *
+ * $Id: JDBCPersistenceManagerService.java 2684 2007-05-15 07:31:30Z timfox $
+ *
+ */
+public class JDBCPersistenceManagerService extends JDBCServiceSupport
+{
+   private PersistenceManager persistenceManager;
+   
+   private boolean started;
+   
+   private boolean usingBatchUpdates;
+   
+   private boolean usingBinaryStream = true;
+   
+   private boolean usingTrailingByte = false;
+   
+   private int maxParams = 100;
+   
+   // Constructors --------------------------------------------------------
+   
+   public JDBCPersistenceManagerService()
+   {      
+   }
+   
+   // ServerPlugin implementation ------------------------------------------
+   
+   public MessagingComponent getInstance()
+   {
+      return persistenceManager;
+   }
+   
+   // ServiceMBeanSupport overrides -----------------------------------------
+   
+   protected synchronized void startService() throws Exception
+   {
+      if (started)
+      {
+         throw new IllegalStateException("Service is already started");
+      }
+      
+      super.startService();
+      
+      try
+      {  
+         TransactionManager tm = getTransactionManagerReference();
+         
+         persistenceManager =
+            new JDBCPersistenceManager(ds, tm, sqlProperties,
+                                       createTablesOnStartup, usingBatchUpdates,
+                                       usingBinaryStream, usingTrailingByte, maxParams);
+         
+         persistenceManager.start();
+         
+         started = true;
+      }
+      catch (Throwable t)
+      {
+         throw ExceptionUtil.handleJMXInvocation(t, this + " startService");
+      } 
+   }
+   
+   protected void stopService() throws Exception
+   {
+      if (!started)
+      {
+         throw new IllegalStateException("Service is not started");
+      }
+      
+      try
+      {
+         persistenceManager.stop();
+         
+         persistenceManager = null;
+         
+         started = false;
+      }
+      catch (Throwable t)
+      {
+         throw ExceptionUtil.handleJMXInvocation(t, this + " startService");
+      } 
+      
+      log.debug(this + " stopped");
+   }
+   
+   // MBean attributes -------------------------------------------------------
+   
+   public boolean isUsingBatchUpdates()
+   {
+      return usingBatchUpdates;
+   }
+   
+   public void setUsingBatchUpdates(boolean b)
+   {
+      usingBatchUpdates = b;
+   }
+   
+   public int getMaxParams()
+   {
+      return maxParams;
+   }
+   
+   public void setMaxParams(int maxParams)
+   {
+      this.maxParams = maxParams;
+   }
+   
+   public boolean isUsingBinaryStream()
+   {
+      return usingBinaryStream;
+   }
+   
+   public void setUsingBinaryStream(boolean b)
+   {
+      usingBinaryStream = b;
+   }
+   
+   public boolean isUsingTrailingByte()
+   {
+      return usingTrailingByte;
+   }
+   
+   public void setUsingTrailingByte(boolean b)
+   {
+      usingTrailingByte = b;
+   }
+}

Added: trunk/src/main/org/jboss/messaging/core/jmx/JDBCServiceSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/jmx/JDBCServiceSupport.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/jmx/JDBCServiceSupport.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,183 @@
+/*
+ * 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.jmx;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import javax.management.MBeanServerInvocationHandler;
+import javax.management.ObjectName;
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
+import javax.transaction.TransactionManager;
+
+import org.jboss.messaging.util.ExceptionUtil;
+import org.jboss.system.ServiceMBeanSupport;
+import org.jboss.tm.TransactionManagerServiceMBean;
+
+/**
+ * MBean wrapper for any service that needs database attributes
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 2684 $</tt>
+ *
+ * $Id: JDBCServiceSupport.java 2684 2007-05-15 07:31:30Z timfox $
+ *
+ */
+public abstract class JDBCServiceSupport extends ServiceMBeanSupport
+{
+   // Constants ------------------------------------------------------------------------------------
+
+   // Static ---------------------------------------------------------------------------------------
+
+   // Attributes -----------------------------------------------------------------------------------
+
+   protected DataSource ds;
+   protected Properties sqlProperties;
+   protected boolean createTablesOnStartup = true;
+
+   private String dataSourceJNDIName;
+   private ObjectName tmObjectName;
+   private TransactionManager tm;
+
+   // Constructors ---------------------------------------------------------------------------------
+
+   // 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!");
+         }
+
+      }
+      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;
+   }
+
+   // Public ---------------------------------------------------------------------------------------
+
+   // Package protected ----------------------------------------------------------------------------
+
+   // Protected ------------------------------------------------------------------------------------
+
+   protected TransactionManager getTransactionManagerReference()
+   {
+      // lazy initialization
+      if (tm == null)
+      {
+         TransactionManagerServiceMBean tms =
+            (TransactionManagerServiceMBean)MBeanServerInvocationHandler.
+            newProxyInstance(getServer(), tmObjectName, TransactionManagerServiceMBean.class, false);
+
+         tm = tms.getTransactionManager();
+      }
+
+      return tm;
+   }
+
+   // Private --------------------------------------------------------------------------------------
+
+   // Inner classes --------------------------------------------------------------------------------
+
+}
+

Added: trunk/src/main/org/jboss/messaging/core/jmx/MessagingPostOfficeService.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/jmx/MessagingPostOfficeService.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/jmx/MessagingPostOfficeService.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,459 @@
+/*
+ * 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.jmx;
+
+import java.util.Set;
+
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanNotificationInfo;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.transaction.TransactionManager;
+
+import org.jboss.jms.server.JMSConditionFactory;
+import org.jboss.jms.server.ServerPeer;
+import org.jboss.jms.server.selector.SelectorFactory;
+import org.jboss.messaging.core.contract.ClusterNotifier;
+import org.jboss.messaging.core.contract.ConditionFactory;
+import org.jboss.messaging.core.contract.FailoverMapper;
+import org.jboss.messaging.core.contract.FilterFactory;
+import org.jboss.messaging.core.contract.JChannelFactory;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.MessagingComponent;
+import org.jboss.messaging.core.contract.PersistenceManager;
+import org.jboss.messaging.core.impl.IDManager;
+import org.jboss.messaging.core.impl.jchannelfactory.MultiplexerJChannelFactory;
+import org.jboss.messaging.core.impl.jchannelfactory.XMLJChannelFactory;
+import org.jboss.messaging.core.impl.postoffice.DefaultFailoverMapper;
+import org.jboss.messaging.core.impl.postoffice.MessagingPostOffice;
+import org.jboss.messaging.core.impl.tx.TransactionRepository;
+import org.jboss.messaging.util.ExceptionUtil;
+import org.w3c.dom.Element;
+
+/**
+ * A MessagingPostOfficeService
+ * 
+ * MBean wrapper for a messaging post office
+ *
+ * @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: 2684 $</tt>
+ *
+ * $Id: ClusteredPostOfficeService.java 2684 2007-05-15 07:31:30Z timfox $
+ *
+ */
+public class MessagingPostOfficeService extends JDBCServiceSupport
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+
+   // Attributes ----------------------------------------------------
+
+   private boolean started;
+
+   // This group of properties is used on JGroups Channel configuration
+   private Element syncChannelConfig;
+   
+   private Element asyncChannelConfig;
+   
+   private ObjectName channelFactoryName;
+   
+   private String syncChannelName;
+   
+   private String asyncChannelName;
+   
+   private String channelPartitionName;
+
+   private ObjectName serverPeerObjectName;
+
+   private String officeName;
+   
+   private long stateTimeout = 5000;
+   
+   private long castTimeout = 5000;
+   
+   private String groupName;
+   
+   private boolean clustered;
+
+   private MessagingPostOffice postOffice;
+
+   // Constructors --------------------------------------------------
+
+   // ServerPlugin implementation -----------------------------------
+
+   public MessagingComponent getInstance()
+   {
+      return postOffice;
+   }
+
+   // NotificationBroadcaster implementation ------------------------
+
+   public void addNotificationListener(NotificationListener listener,
+                                       NotificationFilter filter,
+                                       Object object) throws IllegalArgumentException
+   {
+      postOffice.addNotificationListener(listener, filter, object);
+   }
+
+   public void removeNotificationListener(NotificationListener listener)
+      throws ListenerNotFoundException
+   {
+      postOffice.removeNotificationListener(listener);
+   }
+
+   public MBeanNotificationInfo[] getNotificationInfo()
+   {
+      return postOffice.getNotificationInfo();
+   }
+
+
+   // MBean attributes ----------------------------------------------
+
+   public synchronized ObjectName getServerPeer()
+   {
+      return serverPeerObjectName;
+   }
+
+   public synchronized void setServerPeer(ObjectName on)
+   {
+      if (started)
+      {
+         log.warn("Cannot set attribute when service is started");
+         return;
+      }
+      this.serverPeerObjectName = on;
+   }
+
+   public synchronized String getPostOfficeName()
+   {
+      return officeName;
+   }
+
+   public synchronized void setPostOfficeName(String name)
+   {
+      if (started)
+      {
+         log.warn("Cannot set attribute when service is started");
+         return;
+      }
+      this.officeName = name;
+   }
+
+   public ObjectName getChannelFactoryName()
+   {
+      return channelFactoryName;
+   }
+
+   public void setChannelFactoryName(ObjectName channelFactoryName)
+   {
+      if (started)
+      {
+         log.warn("Cannot set attribute when service is started");
+         return;
+      }
+      this.channelFactoryName = channelFactoryName;
+   }
+
+   public String getSyncChannelName()
+   {
+      return syncChannelName;
+   }
+
+   public void setSyncChannelName(String syncChannelName)
+   {
+      if (started)
+      {
+         log.warn("Cannot set attribute when service is started");
+         return;
+      }
+      this.syncChannelName = syncChannelName;
+   }
+
+   public String getAsyncChannelName()
+   {
+      return asyncChannelName;
+   }
+
+   public void setAsyncChannelName(String asyncChannelName)
+   {
+      if (started)
+      {
+         log.warn("Cannot set attribute when service is started");
+         return;
+      }
+      this.asyncChannelName = asyncChannelName;
+   }
+
+   public String getChannelPartitionName()
+   {
+      return channelPartitionName;
+   }
+
+   public void setChannelPartitionName(String channelPartitionName)
+   {
+      if (started)
+      {
+         log.warn("Cannot set attribute when service is started");
+         return;
+      }
+      this.channelPartitionName = channelPartitionName;
+   }
+
+   public void setSyncChannelConfig(Element config) throws Exception
+   {
+      if (started)
+      {
+         log.warn("Cannot set attribute when service is started");
+         return;
+      }
+      syncChannelConfig = config;
+   }
+
+   public Element getSyncChannelConfig()
+   {
+      return syncChannelConfig;
+   }
+
+   public void setAsyncChannelConfig(Element config) throws Exception
+   {
+      if (started)
+      {
+         log.warn("Cannot set attribute when service is started");
+         return;
+      }
+      asyncChannelConfig = config;
+   }
+
+   public Element getAsyncChannelConfig()
+   {
+      return asyncChannelConfig;
+   }
+
+   public void setStateTimeout(long timeout)
+   {
+      if (started)
+      {
+         log.warn("Cannot set attribute when service is started");
+         return;
+      }
+      this.stateTimeout = timeout;
+   }
+
+   public long getStateTimeout()
+   {
+      return stateTimeout;
+   }
+
+   public void setCastTimeout(long timeout)
+   {
+      if (started)
+      {
+         log.warn("Cannot set attribute when service is started");
+         return;
+      }
+      this.castTimeout = timeout;
+   }
+
+   public long getCastTimeout()
+   {
+      return castTimeout;
+   }
+
+   public void setGroupName(String groupName)
+   {
+      this.groupName = groupName;
+   }
+
+   public String getGroupName()
+   {
+      return groupName;
+   }
+   
+   public boolean isClustered()
+   {
+   	return clustered;
+   }
+   
+   public void setClustered(boolean clustered)
+   {
+   	 if (started)
+       {
+          log.warn("Cannot set attribute when service is started");
+          return;
+       }
+       this.clustered = clustered;
+   }
+   
+   public String listBindings()
+   {
+      return postOffice.printBindingInformation();
+   }
+   
+   public Set getNodeIDView()
+   {
+   	return postOffice.nodeIDView();
+   }
+
+   // Public --------------------------------------------------------
+
+   // Package protected ---------------------------------------------
+
+   // ServiceMBeanSupport overrides ---------------------------------
+
+   protected synchronized void startService() throws Exception
+   {
+      if (started)
+      {
+         throw new IllegalStateException("Service is already started");
+      }
+
+      super.startService();
+
+      try
+      {
+         TransactionManager tm = getTransactionManagerReference();
+
+         ServerPeer serverPeer = (ServerPeer)server.getAttribute(serverPeerObjectName, "Instance");
+         
+         MessageStore ms = serverPeer.getMessageStore();
+         
+         PersistenceManager pm = serverPeer.getPersistenceManagerInstance();
+         
+         TransactionRepository tr = serverPeer.getTxRepository();
+         
+         IDManager idManager = serverPeer.getChannelIDManager();
+         
+         int nodeId = serverPeer.getServerPeerID();
+         
+         ClusterNotifier clusterNotifier = serverPeer.getClusterNotifier();
+
+         ConditionFactory cf = new JMSConditionFactory();
+                  
+         FilterFactory ff = new SelectorFactory();
+         
+         FailoverMapper mapper = new DefaultFailoverMapper();
+
+         JChannelFactory jChannelFactory = null;
+
+         if (channelFactoryName != null)
+         {
+            Object info = null;
+            try
+            {
+               info = server.getMBeanInfo(channelFactoryName);
+            }
+            catch (Exception e)
+            {
+               // log.error("Error", e);
+               // noop... means we couldn't find the channel hence we should use regular
+               // XMLChannelFactories
+            }
+
+            if (info != null)
+            {
+               log.debug(this + " uses MultiplexerJChannelFactory");
+
+               jChannelFactory =
+                  new MultiplexerJChannelFactory(server, channelFactoryName, channelPartitionName,
+                                                 syncChannelName, asyncChannelName);
+            }
+            else
+            {
+               log.debug(this + " uses XMLJChannelFactory");
+               jChannelFactory = new XMLJChannelFactory(syncChannelConfig, asyncChannelConfig);
+            }
+         }
+         else
+         {
+            log.debug(this + " uses XMLJChannelFactory");
+            jChannelFactory = new XMLJChannelFactory(syncChannelConfig, asyncChannelConfig);
+         }
+
+         if (clustered)
+         {         
+	         postOffice =  new MessagingPostOffice(ds, tm, sqlProperties,
+	                                               createTablesOnStartup,
+	                                               nodeId, officeName, ms,
+	                                               pm,
+	                                               tr, ff, cf, idManager,
+	                                               clusterNotifier,
+	                                               groupName,
+	                                               jChannelFactory,
+	                                               stateTimeout, castTimeout,
+	                                               mapper);
+         }
+         else
+         {
+         	postOffice =  new MessagingPostOffice(ds, tm, sqlProperties,
+											                 createTablesOnStartup,
+											                 nodeId, officeName, ms,
+											                 pm,
+											                 tr, ff, cf, idManager,
+											                 clusterNotifier);
+         }
+
+         postOffice.start();
+
+         started = true;
+      }
+      catch (Throwable t)
+      {
+         throw ExceptionUtil.handleJMXInvocation(t, this + " startService");
+      }
+   }
+
+   protected void stopService() throws Exception
+   {
+      if (!started)
+      {
+         throw new IllegalStateException("Service is not started");
+      }
+
+      super.stopService();
+
+      try
+      {
+         postOffice.stop();
+
+         postOffice = null;
+
+         started = false;
+
+         log.debug(this + " stopped");
+      }
+      catch (Throwable t)
+      {
+         throw ExceptionUtil.handleJMXInvocation(t, this + " startService");
+      }
+   }
+
+   // Protected -----------------------------------------------------
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+
+}
+

Deleted: trunk/src/main/org/jboss/messaging/core/local/FirstReceiverPointToPointRouter.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/local/FirstReceiverPointToPointRouter.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/local/FirstReceiverPointToPointRouter.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,197 +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.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-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.Router;
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.tx.Transaction;
-
-/**
- * 
- * 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)
- * then if the consumers are fast then the first receiver will tend to get most or all of the references
- * 
- * @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: 1174 $</tt>
- * $Id: PointToPointRouter.java 1174 2006-08-02 14:14:32Z timfox $
- */
-public class FirstReceiverPointToPointRouter implements Router
-{
-   // Constants -----------------------------------------------------
-
-   private static final Logger log = Logger.getLogger(FirstReceiverPointToPointRouter.class);
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-   
-   private boolean trace = log.isTraceEnabled();
-
-   private List receivers;
-   
-   private volatile boolean makeCopy;
-   
-   private ArrayList receiversCopy;
-
-   // Constructors --------------------------------------------------
-
-   public FirstReceiverPointToPointRouter()
-   {
-      receivers = new ArrayList();
-      
-      makeCopy = true;
-   }
-
-   // Router implementation -----------------------------------------
-
-   public Delivery handle(DeliveryObserver observer, MessageReference ref, Transaction tx)
-   {
-      if (makeCopy)
-      {
-         synchronized (this)
-         {         
-            //We make a copy of the receivers to avoid a race condition:
-            //http://jira.jboss.org/jira/browse/JBMESSAGING-505
-            //Note that we do not make a copy every time - only when the receivers have changed
-         
-            receiversCopy = new ArrayList(receivers);
-            
-            makeCopy = false;
-         }
-      }    
-      
-      Delivery del = null;
-      
-      boolean selectorRejected = false;
-
-      for(Iterator i = receiversCopy.iterator(); i.hasNext(); )
-      {
-         Receiver receiver = (Receiver)i.next();
-
-         try
-         {
-            Delivery d = receiver.handle(observer, ref, tx);
-
-            if (trace) { log.trace("receiver " + receiver + " handled " + ref + " and returned " + d); }
-
-            if (d != null)
-            {
-               if (d.isSelectorAccepted())
-               {
-                  // deliver to the first receiver that accepts
-                  del = d;
-                  break;
-               }
-               else
-               {
-                  selectorRejected = true;
-               }
-            }
-         }
-         catch(Throwable t)
-         {
-            // broken receiver - log the exception and ignore it
-            log.error("The receiver " + receiver + " is broken", t);
-         }
-      }
-
-      if (del == null && selectorRejected)
-      {
-         del = new SimpleDelivery(null, null, true, false);
-      }
-
-      return del;
-   }
-
-
-   public synchronized boolean add(Receiver r)
-   {
-      if (receivers.contains(r))
-      {
-         return false;
-      }
-      
-      receivers.add(r);
-      
-      makeCopy = true;
-      
-      return true;
-   }
-
-
-   public synchronized boolean remove(Receiver r)
-   {            
-      boolean removed = receivers.remove(r);      
-      
-      if (removed)
-      {
-         makeCopy = true;
-      }
-      
-      return removed;
-   }
-
-   public synchronized void clear()
-   {
-      receivers.clear();
-      
-      makeCopy = true;
-   }
-
-   public synchronized boolean contains(Receiver r)
-   {
-      return receivers.contains(r);      
-   }
-
-   public synchronized Iterator iterator()
-   {
-      return receivers.iterator();      
-   }
-   
-   public synchronized int getNumberOfReceivers()
-   {
-      return receivers.size();      
-   }
-
-
-   // Public --------------------------------------------------------
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Deleted: trunk/src/main/org/jboss/messaging/core/local/PagingFilteredQueue.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/local/PagingFilteredQueue.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/local/PagingFilteredQueue.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,136 +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.Delivery;
-import org.jboss.messaging.core.DeliveryObserver;
-import org.jboss.messaging.core.Filter;
-import org.jboss.messaging.core.PagingChannelSupport;
-import org.jboss.messaging.core.Queue;
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.tx.Transaction;
-
-/**
- * 
- * A PagingFilteredQueue
- * 
- * 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: 1295 $</tt>
- *
- * $Id: Queue.java 1295 2006-09-15 17:44:02Z timfox $
- *
- */
-public class PagingFilteredQueue extends PagingChannelSupport implements Queue
-{
-   // Constants -----------------------------------------------------
-   
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-   
-   protected String name;
-   
-   protected Filter filter;
-   
-   // Constructors --------------------------------------------------
-
-   public PagingFilteredQueue(String name, long id, MessageStore ms, PersistenceManager pm,             
-                              boolean acceptReliableMessages, boolean recoverable,
-                              int maxSize, Filter filter)
-   {
-      super(id, ms, pm, acceptReliableMessages, recoverable, maxSize);
-      
-      router = new RoundRobinPointToPointRouter();
-      
-      this.name = name;
-      
-      this.filter = filter;
-   }
-   
-   public PagingFilteredQueue(String name, long id, MessageStore ms, PersistenceManager pm,             
-                              boolean acceptReliableMessages, boolean recoverable,
-                              int maxSize, Filter filter,
-                              int fullSize, int pageSize, int downCacheSize)
-   {
-      super(id, ms, pm, acceptReliableMessages, recoverable,
-            maxSize, fullSize, pageSize, downCacheSize);
-      
-      router = new RoundRobinPointToPointRouter();
-      
-      this.name = name;
-      
-      this.filter = filter;
-   }
-   
-   // Queue implementation
-   // ---------------------------------------------------------------
-   
-   public boolean isClustered()
-   {
-      return false;
-   }
-   
-   public String getName()
-   {
-      return name;
-   }
-      
-   public Filter getFilter()
-   {
-      return filter;
-   }
-    
-   // Channel implementation ----------------------------------------   
-   
-   public Delivery handle(DeliveryObserver sender, MessageReference ref, Transaction tx)
-   {
-      if (filter == null || filter.accept(ref.getMessage()))
-      {
-         return super.handle(sender, ref, tx);
-      }
-      else
-      {
-         return new SimpleDelivery(this, ref, true, false);
-      }
-   }
-   
-   // Public --------------------------------------------------------
-   
-   public String toString()
-   {
-      return "Queue[" + getChannelID() + "/" + this.getName() +  "]";
-   }
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Deleted: trunk/src/main/org/jboss/messaging/core/local/RoundRobinPointToPointRouter.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/local/RoundRobinPointToPointRouter.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/local/RoundRobinPointToPointRouter.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,232 +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.ArrayList;
-import java.util.Iterator;
-
-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.Router;
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.tx.Transaction;
-
-/**
- *  
- * 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
- * consumers rather than in contiguous blocks.
- *  
- * @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 $</tt>
- * $Id: $
- */
-public class RoundRobinPointToPointRouter implements Router
-{
-   // Constants ------------------------------------------------------------------------------------
-
-   private static final Logger log = Logger.getLogger(RoundRobinPointToPointRouter.class);
-
-   // Static ---------------------------------------------------------------------------------------
-   
-   // Attributes -----------------------------------------------------------------------------------
-   
-   private boolean trace = log.isTraceEnabled();
-
-   // it's important that we're actually using an ArrayList for fast array access
-   private ArrayList receivers;
-   
-   private int target;
-   
-   private volatile boolean makeCopy;
-   
-   private ArrayList receiversCopy;
-   
-   // Constructors ---------------------------------------------------------------------------------
-
-   public RoundRobinPointToPointRouter()
-   {
-      receivers = new ArrayList();
-      
-      target = 0;
-      
-      makeCopy = true;
-   }
-
-   // Router implementation ------------------------------------------------------------------------
-   
-   public Delivery handle(DeliveryObserver observer, MessageReference ref, Transaction tx)
-   {             
-      if (makeCopy)
-      {
-         synchronized (this)
-         {         
-            // We make a copy of the receivers to avoid a race condition:
-            // http://jira.jboss.org/jira/browse/JBMESSAGING-505
-            // Note that we do not make a copy every time - only when the receivers have changed
-         
-            receiversCopy = new ArrayList(receivers);
-            
-            if (target >= receiversCopy.size())
-            {
-               target = 0;
-            }
-         
-            makeCopy = false;
-         }
-      }      
-      
-      if (receiversCopy.isEmpty())
-      {
-         return null;
-      }
-
-      Delivery del = null;
-      
-      boolean selectorRejected = false;
-      
-      int initial = target;
-
-      while (true)
-      {
-         Receiver r = (Receiver)receiversCopy.get(target);
-
-         try
-         {
-            Delivery d = r.handle(observer, ref, tx);
-
-            if (trace) { log.trace("receiver " + r + " handled " + ref + " and returned " + d); }
-
-            if (d != null)
-            {
-               if (d.isSelectorAccepted())
-               {
-                  // deliver to the first receiver that accepts
-                  del = d;
-                  
-                  incTarget();
-                                                     
-                  break;
-               }
-               else
-               {
-                  selectorRejected = true;
-               }
-            }
-         }
-         catch(Throwable t)
-         {
-            // broken receiver - log the exception and ignore it
-            log.error("The receiver " + r + " is broken", t);
-         }
-
-         incTarget();
-
-         // if we've tried them all then we break
-         if (target == initial)
-         {
-            break;
-         }
-      }
-
-      if (del == null && selectorRejected)
-      {
-         del = new SimpleDelivery(null, null, true, false);
-      }
-
-      return del;      
-   }
-   
-   public synchronized boolean add(Receiver r)
-   {
-      if (receivers.contains(r))
-      {
-         return false;
-      }
-
-      receivers.add(r);
-      
-      makeCopy = true;
-      
-      return true;      
-   }
-
-   public synchronized boolean remove(Receiver r)
-   {
-      boolean removed = receivers.remove(r);
-      
-      if (removed)
-      {
-         makeCopy = true;
-      }
-      
-      return removed;      
-   }
-
-   public synchronized void clear()
-   {
-      receivers.clear();
-      
-      makeCopy = true;    
-   }
-
-   public synchronized boolean contains(Receiver r)
-   {
-      return receivers.contains(r);     
-   }
-
-   public synchronized Iterator iterator()
-   {
-      return receivers.iterator();      
-   }
-   
-   public synchronized int getNumberOfReceivers()
-   {
-      return receivers.size();      
-   }
-
-   // Public ---------------------------------------------------------------------------------------
-
-   // Package protected ----------------------------------------------------------------------------
-   
-   // Protected ------------------------------------------------------------------------------------
-
-   // Private --------------------------------------------------------------------------------------
-   
-   private void incTarget()
-   {
-      target++;
-      
-      if (target == receiversCopy.size())
-      {
-         target = 0;
-      }
-   }
-   
-   // Inner classes --------------------------------------------------------------------------------
-}
-

Deleted: trunk/src/main/org/jboss/messaging/core/message/CoreMessage.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/message/CoreMessage.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/message/CoreMessage.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,81 +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.message;
-
-import java.util.Map;
-
-/**
- * @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 CoreMessage extends MessageSupport
-{
-   // Constants -----------------------------------------------------
-
-   public static final byte TYPE = 127;
-
-   // Attributes ----------------------------------------------------
-
-   // Constructors --------------------------------------------------
-
-   /**
-    * Required by externalization.
-    */
-   public CoreMessage()
-   {
-   }
-   
-   public CoreMessage(long messageID,
-                      boolean reliable,
-                      long expiration,
-                      long timestamp,
-                      byte priority,
-                      Map headers,
-                      byte[] payload)
-   {
-      super(messageID, reliable, expiration, timestamp, priority, headers, payload);
-   }
-
-   // Public --------------------------------------------------------
-
-   public String toString()
-   {
-      return "CoreMessage["+messageID+"]";
-   }
-   
-   public byte getType()
-   {
-      return TYPE;
-   }
-
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-
-}

Deleted: trunk/src/main/org/jboss/messaging/core/message/Message.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/message/Message.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/message/Message.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,123 +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.message;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.jboss.messaging.util.Streamable;
-
-/**
- * A message is a routable instance that has a payload. The payload is opaque to the messaging
- * system.
- *
- * When implementing this interface, make sure you override equals() and hashCode() such that two
- * Message instances with equals IDs are equal.
- *
- * @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 interface Message extends Streamable
-{
-   static final String FAILED_NODE_ID = "FAILED_NODE_ID";
-
-   long getMessageID();
-
-   /**
-    * @return true if the delivery must be guaranteed for this routable, false otherwise.
-    */
-   boolean isReliable();
-   
-   /**
-    * @return the time (in GMT milliseconds) when this routable expires and must be removed
-    *         from the system. A zero value means this routable never expires.
-    */
-   long getExpiration();
-
-   boolean isExpired();
-   
-   void setExpiration(long expiration);
-   
-   /**
-    * @return the time (in GMT milliseconds) when this routable was delivered to the provider.
-    */
-   long getTimestamp();
-   
-   byte getPriority();
-   
-   void setPriority(byte priority);
-
-   /**
-    * Binds a header. If the header map previously contained a mapping for this name, the old value
-    * is replaced by the specified value.
-    *
-    * @return the value associated with the name or null if there is no mapping for the name. A null
-    *         can also indicate that the header map previously associated null with the specified
-    *         name.
-    */
-   Object putHeader(String name, Object value);
-
-   /**
-    * Returns the value corresponding to the header name. Returns null if the map contains no
-    * mapping for the name. A return value of null does not necessarily indicate that the map
-    * contains no mapping for the name; it's also possible that the map explicitly maps the name to
-    * null. The containsHeader() operation may be used to distinguish these two cases.
-    *
-    * @return the value associated with the header, or null if there is no mapping for the header.
-    */
-   Object getHeader(String name);
-
-   /**
-    * Removes the header.
-    *
-    * @return previous value associated with the header, or null if there was no mapping.
-    */
-   Object removeHeader(String name);
-
-   /**
-    * Returns true if the Routable contains the specified header.
-    */
-   boolean containsHeader(String name);
-   
-   void setHeaders(Map headers);
-
-   /**
-    * Returns a copy of the header name set.
-    */
-   Set getHeaderNames();
-   
-   Map getHeaders();
-   
-   Object getPayload();
-   
-   byte[] getPayloadAsByteArray();
-    
-   boolean isPersisted();
-   
-   void setPersisted(boolean persisted);
-   
-   byte getType();
-   
-}

Deleted: trunk/src/main/org/jboss/messaging/core/message/MessageFactory.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/message/MessageFactory.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/message/MessageFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,170 +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.message;
-
-import java.util.Map;
-
-import org.jboss.jms.message.JBossBytesMessage;
-import org.jboss.jms.message.JBossMapMessage;
-import org.jboss.jms.message.JBossMessage;
-import org.jboss.jms.message.JBossObjectMessage;
-import org.jboss.jms.message.JBossStreamMessage;
-import org.jboss.jms.message.JBossTextMessage;
-
-/**
- * @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 MessageFactory
-{
-   // Constants ------------------------------------------------------------------------------------
-
-   // Static ---------------------------------------------------------------------------------------
-
-   public static Message createMessage(byte type)
-   {
-      Message m = null;
-      
-      if (type == JBossMessage.TYPE) //1
-      {
-         m = new JBossMessage();
-      }
-      else if (type == JBossObjectMessage.TYPE) //2
-      {
-         m = new JBossObjectMessage();
-      }
-      else if (type == JBossTextMessage.TYPE)  //3
-      {
-         m = new JBossTextMessage();
-      }
-      else if (type == JBossBytesMessage.TYPE)  //4
-      {
-         m = new JBossBytesMessage();
-      }
-      else if (type == JBossMapMessage.TYPE)  //5
-      {
-         m = new JBossMapMessage();
-      }
-      else if (type == JBossStreamMessage.TYPE) //6
-      {
-         m = new JBossStreamMessage();
-      }
-      else if (type == CoreMessage.TYPE) //127
-      {
-         m = new CoreMessage();
-      }
-      else
-      {
-         throw new IllegalArgumentException("Invalid type " + type);
-      }
-     
-      return m;
-   }
-   
-   /*
-    * Create a message from persistent storage
-    */
-   public static Message createMessage(long messageID,
-                                       boolean reliable, 
-                                       long expiration, 
-                                       long timestamp,
-                                       byte priority,
-                                       Map headers,
-                                       byte[] payload,                                                                                    
-                                       byte type)
-
-   {
-      Message m = null;
-      
-      switch (type)
-      {
-         case JBossMessage.TYPE:
-         {
-            m = new JBossMessage(messageID, reliable, expiration,
-                                 timestamp, priority, headers, payload);
-            break;
-         }
-         case JBossObjectMessage.TYPE:
-         {
-            m =  new JBossObjectMessage(messageID, reliable, expiration,
-                                        timestamp, priority, headers, payload);
-            break;
-         }
-         case JBossTextMessage.TYPE:
-         {
-            m = new JBossTextMessage(messageID, reliable, expiration,
-                                     timestamp, priority, headers, payload);
-            break;
-         }
-         case JBossBytesMessage.TYPE:
-         {
-            m = new JBossBytesMessage(messageID, reliable, expiration,
-                                      timestamp, priority, headers, payload);
-            break;
-         }
-         case JBossMapMessage.TYPE:
-         {
-            m = new JBossMapMessage(messageID, reliable, expiration,
-                                    timestamp, priority, headers, payload);
-            break;
-         }
-         case JBossStreamMessage.TYPE:
-         {
-            m = new JBossStreamMessage(messageID, reliable, expiration,
-                                       timestamp, priority, headers, payload);
-            break;
-         }
-         case CoreMessage.TYPE:
-         {
-            m = new CoreMessage(messageID, reliable, expiration,
-                                timestamp, priority, headers, payload);
-            break;
-         }
-         default:
-         {
-            throw new IllegalArgumentException("Unknown type " + type);       
-         }
-      }
-      
-      m.setPersisted(true);
-      
-      return m;
-   }
-
-   // Attributes -----------------------------------------------------------------------------------
-   
-   // Constructors ---------------------------------------------------------------------------------
-   
-   // Public ---------------------------------------------------------------------------------------
-
-   // Package protected ----------------------------------------------------------------------------
-   
-   // Protected ------------------------------------------------------------------------------------
-   
-   // Private --------------------------------------------------------------------------------------
-   
-   // Inner classes --------------------------------------------------------------------------------   
-}
-

Deleted: trunk/src/main/org/jboss/messaging/core/message/MessageHolder.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/message/MessageHolder.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/message/MessageHolder.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,81 +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.message;
-
-
-/**
- * 
- * A MessageHolder.
- * 
- * @author <a href="tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-class MessageHolder
-{
-   /*
-    * The number of channels *currently in memory* that hold a reference to the message
-    * We need this so we know when to evict the message from the store (when it reaches zero)
-    * Note that we also maintain a persistent channel count on the message itself.
-    * This is the total number of channels whether loaded in memory or not that hold a reference to the
-    * message and is needed to know when it is safe to remove the message from the db
-    */
-   private int inMemoryChannelCount;
-   
-   private Message msg;
-   
-   private SimpleMessageStore ms;
-   
-   public MessageHolder(Message msg, SimpleMessageStore ms)
-   {
-      this.msg = msg;
-      this.ms = ms;
-   }    
-   
-   public synchronized void incrementInMemoryChannelCount()
-   {            
-      inMemoryChannelCount++;
-   }
-   
-   public synchronized void decrementInMemoryChannelCount()
-   {
-      inMemoryChannelCount--;      
-
-      if (inMemoryChannelCount == 0)
-      {
-         // can remove the message from the message store
-         ms.forgetMessage(msg.getMessageID());
-      }
-   }
-   
-   public synchronized int getInMemoryChannelCount()
-   {
-      return inMemoryChannelCount;
-   }
- 
-   public Message getMessage()
-   {
-      return msg;
-   }   
-}

Deleted: trunk/src/main/org/jboss/messaging/core/message/MessageReference.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/message/MessageReference.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/message/MessageReference.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,65 +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.message;
-
-
-/**
- * A reference to a message.
- * 
- * 
- * @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 MessageReference
-{      
-   long getPagingOrder();
-   
-   void setPagingOrder(long order);   
-   
-   void releaseMemoryReference();
-   
-   MessageReference copy();
-   
-   Message getMessage();
-   
-   /**
-    * 
-    * @return The time in the future that delivery will be delayed until, or zero if
-    * no scheduled delivery will occur
-    */
-   long getScheduledDeliveryTime();
-   
-   void setScheduledDeliveryTime(long scheduledDeliveryTime);
-   
-   /**
-    * @return the number of times delivery has been attempted for this routable
-    */
-   int getDeliveryCount();
-   
-   void setDeliveryCount(int deliveryCount);
-   
-   
-
-}

Deleted: trunk/src/main/org/jboss/messaging/core/message/MessageSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/message/MessageSupport.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/message/MessageSupport.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,454 +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.message;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import org.jboss.logging.Logger;
-import org.jboss.messaging.util.StreamUtils;
-
-/**
- * A message base.
- * 
- * @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>
- * 
- * Note this class is only serializable so messages can't be returned from JMX operations
- * e.g. listAllMessages.
- * For normal message transportation serialization is not used
- * 
- * $Id$
- */
-public abstract class MessageSupport implements Message, Serializable
-{
-	// Constants -----------------------------------------------------
-
-	private static final Logger log = Logger.getLogger(MessageSupport.class);
-
-	// Attributes ----------------------------------------------------
-
-	private boolean trace = log.isTraceEnabled();
-
-	protected long messageID;
-
-	protected boolean reliable;
-
-	/** GMT milliseconds at which this message expires. 0 means never expires * */
-	protected long expiration;
-
-	protected long timestamp;
-
-	protected Map headers;
-
-	protected byte priority;
-
-	// Must be hidden from subclasses
-	private transient Object payload;
-
-	// Must be hidden from subclasses
-	private byte[] payloadAsByteArray;
-
-	private transient boolean persisted;
-
-	// Constructors --------------------------------------------------
-
-	/*
-	 * Construct a message for deserialization or streaming
-	 */
-	public MessageSupport()
-	{
-	}
-
-	/*
-	 * Construct a message using default values
-	 */
-	public MessageSupport(long messageID)
-	{
-		this(messageID, false, 0, System.currentTimeMillis(), (byte) 4, null,
-				null);
-	}
-
-	/*
-	 * Construct a message using specified values
-	 */
-	public MessageSupport(long messageID, boolean reliable, long expiration,
-			long timestamp, byte priority, Map headers, byte[] payloadAsByteArray)
-	{
-		this.messageID = messageID;
-		this.reliable = reliable;
-		this.expiration = expiration;
-		this.timestamp = timestamp;
-		this.priority = priority;
-		if (headers == null)
-		{
-			this.headers = new HashMap();
-		} else
-		{
-			this.headers = new HashMap(headers);
-		}
-
-		this.payloadAsByteArray = payloadAsByteArray;
-	}
-
-	/*
-	 * Copy constructor
-	 * 
-	 * Does a shallow copy of the payload
-	 */
-	protected MessageSupport(MessageSupport that)
-	{
-		this.messageID = that.messageID;
-		this.reliable = that.reliable;
-		this.expiration = that.expiration;
-		this.timestamp = that.timestamp;
-		this.headers = new HashMap(that.headers);
-		this.priority = that.priority;
-		this.payload = that.payload;
-		this.payloadAsByteArray = that.payloadAsByteArray;
-	}
-
-	// Message implementation ----------------------------------------
-
-	public long getMessageID()
-	{
-		return messageID;
-	}
-
-	public boolean isReliable()
-	{
-		return reliable;
-	}
-
-	public long getExpiration()
-	{
-		return expiration;
-	}
-
-	public void setExpiration(long expiration)
-	{
-		this.expiration = expiration;
-	}
-
-	public long getTimestamp()
-	{
-		return timestamp;
-	}
-
-	public Object putHeader(String name, Object value)
-	{
-		return headers.put(name, value);
-	}
-
-	public Object getHeader(String name)
-	{
-		return headers.get(name);
-	}
-
-	public Object removeHeader(String name)
-	{
-		return headers.remove(name);
-	}
-
-	public boolean containsHeader(String name)
-	{
-		return headers.containsKey(name);
-	}
-
-	public Set getHeaderNames()
-	{
-		return headers.keySet();
-	}
-
-	public Map getHeaders()
-	{
-		return headers;
-	}
-
-	public void setHeaders(Map headers)
-	{
-		this.headers = headers;
-	}
-
-	public byte getPriority()
-	{
-		return priority;
-	}
-
-	public void setPriority(byte priority)
-	{
-		this.priority = priority;
-	}
-
-	public boolean isReference()
-	{
-		return false;
-	}
-
-	public synchronized byte[] getPayloadAsByteArray()
-	{
-		if (payloadAsByteArray == null && payload != null)
-		{
-			// convert the payload into a byte array and store internally
-
-			// TODO - investigate how changing the buffer size effects
-			// performance
-
-			// Ideally I would like to use the pre-existing DataOutputStream and
-			// not create another one - but would then have to add markers on the
-			// stream
-			// to signify the end of the payload
-			// This would have the advantage of us not having to allocate buffers
-			// here
-			// We could do this by creating our own FilterOutputStream that makes
-			// sure
-			// the end of marker sequence doesn't occur in the payload
-
-			final int BUFFER_SIZE = 2048;
-
-			try
-			{
-				ByteArrayOutputStream bos = new ByteArrayOutputStream(BUFFER_SIZE);
-				DataOutputStream daos = new DataOutputStream(bos);
-				writePayload(daos, payload);
-				daos.close();
-				payloadAsByteArray = bos.toByteArray();
-				payload = null;
-			} catch (Exception e)
-			{
-				RuntimeException e2 = new RuntimeException(e.getMessage());
-				e2.setStackTrace(e.getStackTrace());
-				throw e2;
-			}
-		}
-		return payloadAsByteArray;
-	}
-
-	/**
-	 * Warning! Calling getPayload will cause the payload to be deserialized so
-	 * should not be called on the server.
-	 */
-	public synchronized Object getPayload()
-	{
-		if (payload != null)
-		{
-			return payload;
-		}
-		else if (payloadAsByteArray != null)
-		{
-			// deserialize the payload from byte[]
-
-			// TODO use the same DataInputStream as in the read() method and
-			// add markers on the stream to represent end of payload
-			ByteArrayInputStream bis = new ByteArrayInputStream(payloadAsByteArray);
-			DataInputStream dis = new DataInputStream(bis);
-			try
-			{
-				payload = readPayload(dis, payloadAsByteArray.length);
-			}
-			catch (Exception e)
-			{
-				RuntimeException e2 = new RuntimeException(e.getMessage());
-				e2.setStackTrace(e.getStackTrace());
-				throw e2;
-			}
-
-			payloadAsByteArray = null;
-		   return payload;
-		}
-		else
-		{
-			return null;
-		}
-	}
-
-	public void setPayload(Serializable payload)
-	{
-		this.payload = payload;
-	}
-
-	protected void clearPayloadAsByteArray()
-	{
-		this.payloadAsByteArray = null;
-	}
-
-	public synchronized boolean isPersisted()
-	{
-		return persisted;
-	}
-
-	public synchronized void setPersisted(boolean persisted)
-	{
-		this.persisted = persisted;
-	}
-
-	public boolean isExpired()
-	{
-		if (expiration == 0)
-		{
-			return false;
-		}
-		long overtime = System.currentTimeMillis() - expiration;
-		if (overtime >= 0)
-		{
-			// discard it
-			if (trace)
-			{
-				log.trace(this + " expired by " + overtime + " ms");
-			}
-
-			return true;
-		}
-		return false;
-	}
-
-	// Public --------------------------------------------------------
-
-	public boolean equals(Object o)
-	{
-		if (this == o)
-		{
-			return true;
-		}
-		if (!(o instanceof MessageSupport))
-		{
-			return false;
-		}
-		MessageSupport that = (MessageSupport) o;
-		return that.messageID == this.messageID;
-	}
-
-	public int hashCode()
-	{
-		return (int) ((this.messageID >>> 32) ^ this.messageID);
-	}
-
-	public String toString()
-	{
-		return "M[" + messageID + "]";
-	}
-
-	// Streamable implementation ---------------------------------
-
-	public void write(DataOutputStream out) throws Exception
-	{
-		out.writeLong(messageID);
-
-		out.writeBoolean(reliable);
-
-		out.writeLong(expiration);
-
-		out.writeLong(timestamp);
-
-		StreamUtils.writeMap(out, headers, true);
-
-		out.writeByte(priority);
-
-		byte[] bytes = getPayloadAsByteArray();
-
-		if (bytes != null)
-		{
-			out.writeInt(bytes.length);
-
-			out.write(bytes);
-		} else
-		{
-			out.writeInt(0);
-		}
-	}
-
-	public void read(DataInputStream in) throws Exception
-	{
-		messageID = in.readLong();
-
-		reliable = in.readBoolean();
-
-		expiration = in.readLong();
-
-		timestamp = in.readLong();
-
-		headers = StreamUtils.readMap(in, true);
-
-		priority = in.readByte();
-
-		int length = in.readInt();
-
-		if (length == 0)
-		{
-			// no payload
-			payloadAsByteArray = null;
-		} else
-		{
-			payloadAsByteArray = new byte[length];
-
-			in.readFully(payloadAsByteArray);
-		}
-	}
-
-	// Package protected ---------------------------------------------
-
-	// Protected -----------------------------------------------------
-
-	/**
-	 * Override this if you want more sophisticated payload externalization.
-	 * 
-	 * @throws Exception
-	 *            TODO
-	 */
-	protected void writePayload(DataOutputStream out, Object thePayload)
-			throws Exception
-	{
-		StreamUtils.writeObject(out, thePayload, true, true);
-	}
-
-	/**
-	 * Override this if you want more sophisticated payload externalization.
-	 * 
-	 * @throws Exception
-	 *            TODO
-	 */
-	protected Object readPayload(DataInputStream in, int length)
-			throws Exception
-	{
-		return StreamUtils.readObject(in, true);
-	}
-
-	/**
-	 * It makes sense to use this method only from within JBossBytesMessage
-	 * (optimization). Using it from anywhere else will lead to corrupted data.
-	 */
-	protected final void copyPayloadAsByteArrayToPayload()
-	{
-		payload = payloadAsByteArray;
-	}
-
-	// Private -------------------------------------------------------
-
-	// Inner classes -------------------------------------------------
-}

Deleted: trunk/src/main/org/jboss/messaging/core/message/SimpleMessageReference.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/message/SimpleMessageReference.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/message/SimpleMessageReference.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,179 +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.message;
-
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-
-/**
- * A Simple MessageReference implementation.
- * 
- * Note that we do not need WeakReferences to message/holder objects since with the new
- * lazy loading schema we guarantee that if a message ref is in memory - it's corresponding message is
- * in memory too
- *
- * @author <a href="mailto:tim.fox at jboss.com>Tim Fox</a>
- * @version <tt>1.3</tt>
- *
- * SimpleMessageReference.java,v 1.3 2006/02/23 17:45:57 timfox Exp
- */
-public class SimpleMessageReference implements MessageReference
-{   
-   private static final Logger log = Logger.getLogger(SimpleMessageReference.class);
-   
-   // Attributes ----------------------------------------------------
-
-   private boolean trace = log.isTraceEnabled();
-   
-   protected transient MessageStore ms;
-   
-   private MessageHolder holder;
-   
-   private long pagingOrder = -1;
-   
-   private boolean released;
-      
-   private int deliveryCount;   
-   
-   private long scheduledDeliveryTime;
-   
-   
-   // Constructors --------------------------------------------------
-
-   /**
-    * Required by externalization.
-    */
-   public SimpleMessageReference()
-   {
-      if (trace) { log.trace("Creating using default constructor"); }
-   }
-
-   public SimpleMessageReference(SimpleMessageReference other)
-   {
-      this.ms = other.ms;
-      
-      this.holder = other.holder;
-      
-      this.pagingOrder = other.pagingOrder;
-      
-      this.released = other.released;
-      
-      this.deliveryCount = other.deliveryCount;
-      
-      this.scheduledDeliveryTime = other.scheduledDeliveryTime;            
-   }
-   
-   protected SimpleMessageReference(MessageHolder holder, MessageStore ms)
-   {
-      this.holder = holder;
-      
-      this.ms = ms;
-   }
-
-   // Message implementation ----------------------------------------
-
-   public boolean isReference()
-   {
-      return true;
-   }
-
-   // MessageReference implementation -------------------------------
-   
-   public int getDeliveryCount()
-   {
-      return deliveryCount;
-   }
-   
-   public void setDeliveryCount(int deliveryCount)
-   {
-      this.deliveryCount = deliveryCount;
-   }
-   
-   public long getScheduledDeliveryTime()
-   {
-      return scheduledDeliveryTime;
-   }
-
-   public void setScheduledDeliveryTime(long scheduledDeliveryTime)
-   {
-      this.scheduledDeliveryTime = scheduledDeliveryTime;
-   }
-      
-   public Message getMessage()
-   {
-      return holder.getMessage();
-   }         
-   
-   public void releaseMemoryReference()
-   {
-      if (released)
-      {
-         //Do nothing -
-         //It's possible releaseMemoryReference can be called more than once on a reference since it's
-         //allowable that acknowledge is called more than once for a delivery and each call will call this
-         //method - so we don't want to throw an exception
-         return;
-      }
-      holder.decrementInMemoryChannelCount();
-      
-      released = true;
-   }
-   
-   public int getInMemoryChannelCount()
-   {
-      return holder.getInMemoryChannelCount();
-   }
-  
-   public long getPagingOrder()
-   {
-      return pagingOrder;
-   }
-   
-   public void setPagingOrder(long order)
-   {
-      this.pagingOrder = order;
-   }
-   
-   public MessageReference copy()
-   {
-      SimpleMessageReference ref = new SimpleMessageReference(this);
-      
-      ref.holder.incrementInMemoryChannelCount();
-      
-      return ref;
-   }
-   
-   // Public --------------------------------------------------------
-
-   public String toString()
-   {
-      return "Reference[" + getMessage().getMessageID() + "]:" + (getMessage().isReliable() ? "RELIABLE" : "NON-RELIABLE");
-   }
-
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------   
-   
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-}
\ No newline at end of file

Deleted: trunk/src/main/org/jboss/messaging/core/message/SimpleMessageStore.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/message/SimpleMessageStore.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/message/SimpleMessageStore.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,173 +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.message;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-
-/**
- * A MessageStore implementation.
- * 
- * @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 SimpleMessageStore implements MessageStore
-{
-   // Constants -----------------------------------------------------
-
-   private static final Logger log = Logger.getLogger(SimpleMessageStore.class);
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-   
-   private boolean trace = log.isTraceEnabled();
- 
-   // <messageID - MessageHolder>
-   private Map messages;
-
-   // Constructors --------------------------------------------------
-
-   public SimpleMessageStore()
-   {  
-      messages = new HashMap();
-
-      log.debug(this + " initialized");
-   }
-
-   // MessageStore implementation ---------------------------
-
-   public Object getInstance()
-   {
-      return this;
-   }
-
-   // 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)
-   {
-      MessageHolder holder;
-      
-      synchronized (this)
-      {         
-         holder = (MessageHolder)messages.get(new Long(m.getMessageID()));
-         
-         if (holder == null)
-         {      
-            holder = addMessage(m);
-         }
-      }
-      holder.incrementInMemoryChannelCount();
-      
-      MessageReference ref = new SimpleMessageReference(holder, this);
-      
-      if (trace) { log.trace(this + " generated " + ref + " for " + m); }
-      
-      return ref;
-   }
-
-   public MessageReference reference(long messageID)
-   {
-      MessageHolder holder;
-      
-      synchronized (this)
-      {
-         holder = (MessageHolder)messages.get(new Long(messageID));         
-      }
-      
-      if (holder == null)
-      {
-         return null;
-      }
-       
-      MessageReference ref = new SimpleMessageReference(holder, this);
-      
-      if (trace) { log.trace(this + " generates " + ref + " for " + messageID); }
-      
-      holder.incrementInMemoryChannelCount();
-      
-      return ref;      
-   }
-   
-
-   public boolean forgetMessage(long messageID)
-   {
-      return messages.remove(new Long(messageID)) != null;
-   }
-   
-   public int size()
-   {
-      return messages.size();
-   }
-   
-   public List messageIds()
-   {
-      return new ArrayList(messages.keySet());
-   }
-   
-   // MessagingComponent implementation --------------------------------
-   
-   public void start() throws Exception
-   {
-      //NOOP
-   }
-   
-   public void stop() throws Exception
-   {
-      //NOOP
-   }
-
-   // Public --------------------------------------------------------
-   
-   public String toString()
-   {
-      return "MemoryStore[" + System.identityHashCode(this) + "]";
-   }
-
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-   
-   protected MessageHolder addMessage(Message m)
-   {
-      MessageHolder holder = new MessageHolder(m, this);
-      
-      messages.put(new Long(m.getMessageID()), holder);
-      
-      return holder;
-   }
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-      
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/ClusteredPostOfficeService.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/ClusteredPostOfficeService.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/ClusteredPostOfficeService.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,491 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin;
-
-import java.util.Collections;
-import java.util.Set;
-
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanNotificationInfo;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.transaction.TransactionManager;
-
-import org.jboss.jms.server.JMSConditionFactory;
-import org.jboss.jms.server.ServerPeer;
-import org.jboss.jms.server.selector.SelectorFactory;
-import org.jboss.messaging.core.FilterFactory;
-import org.jboss.messaging.core.plugin.contract.ConditionFactory;
-import org.jboss.messaging.core.plugin.contract.FailoverMapper;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.plugin.postoffice.cluster.ClusterRouterFactory;
-import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
-import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultFailoverMapper;
-import org.jboss.messaging.core.plugin.postoffice.cluster.MessagePullPolicy;
-import org.jboss.messaging.core.plugin.postoffice.cluster.Peer;
-import org.jboss.messaging.core.plugin.postoffice.cluster.jchannelfactory.JChannelFactory;
-import org.jboss.messaging.core.plugin.postoffice.cluster.jchannelfactory.MultiplexerJChannelFactory;
-import org.jboss.messaging.core.plugin.postoffice.cluster.jchannelfactory.XMLJChannelFactory;
-import org.jboss.messaging.core.tx.TransactionRepository;
-import org.jboss.messaging.util.ExceptionUtil;
-import org.w3c.dom.Element;
-
-/**
- * A ClusteredPostOfficeService
- * 
- * MBean wrapper for a clustered post office
- *
- * @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$</tt>
- *
- * $Id$
- *
- */
-public class ClusteredPostOfficeService extends JDBCServiceSupport implements Peer
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-
-   // Attributes ----------------------------------------------------
-
-   private boolean started;
-
-   // This group of properties is used on JGroups Channel configuration
-   private Element syncChannelConfig;
-   private Element asyncChannelConfig;
-   private ObjectName channelFactoryName;
-   private String syncChannelName;
-   private String asyncChannelName;
-   private String channelPartitionName;
-
-   private ObjectName serverPeerObjectName;
-
-   private String officeName;
-   private long stateTimeout = 5000;
-   private long castTimeout = 5000;
-   private String groupName;
-   private long statsSendPeriod = 1000;
-   private String clusterRouterFactory;
-   private String messagePullPolicy;
-   private int threadPoolSize = 50;
-
-   private DefaultClusteredPostOffice postOffice;
-
-   // Constructors --------------------------------------------------
-
-   // ServerPlugin implementation -----------------------------------
-
-   public MessagingComponent getInstance()
-   {
-      return postOffice;
-   }
-
-   // Peer implementation -------------------------------------------
-
-   public Set getNodeIDView()
-   {
-      if (postOffice == null)
-      {
-         return Collections.EMPTY_SET;
-      }
-
-      return postOffice.getNodeIDView();
-   }
-
-   // NotificationBroadcaster implementation ------------------------
-
-   public void addNotificationListener(NotificationListener listener,
-                                       NotificationFilter filter,
-                                       Object object) throws IllegalArgumentException
-   {
-      postOffice.addNotificationListener(listener, filter, object);
-   }
-
-   public void removeNotificationListener(NotificationListener listener)
-      throws ListenerNotFoundException
-   {
-      postOffice.removeNotificationListener(listener);
-   }
-
-   public MBeanNotificationInfo[] getNotificationInfo()
-   {
-      return postOffice.getNotificationInfo();
-   }
-
-
-   // MBean attributes ----------------------------------------------
-
-   public synchronized ObjectName getServerPeer()
-   {
-      return serverPeerObjectName;
-   }
-
-   public synchronized void setServerPeer(ObjectName on)
-   {
-      if (started)
-      {
-         log.warn("Cannot set attribute when service is started");
-         return;
-      }
-      this.serverPeerObjectName = on;
-   }
-
-   public synchronized String getPostOfficeName()
-   {
-      return officeName;
-   }
-
-   public synchronized void setPostOfficeName(String name)
-   {
-      if (started)
-      {
-         log.warn("Cannot set attribute when service is started");
-         return;
-      }
-      this.officeName = name;
-   }
-
-   public ObjectName getChannelFactoryName()
-   {
-      return channelFactoryName;
-   }
-
-   public void setChannelFactoryName(ObjectName channelFactoryName)
-   {
-      if (started)
-      {
-         log.warn("Cannot set attribute when service is started");
-         return;
-      }
-      this.channelFactoryName = channelFactoryName;
-   }
-
-   public String getSyncChannelName()
-   {
-      return syncChannelName;
-   }
-
-   public void setSyncChannelName(String syncChannelName)
-   {
-      if (started)
-      {
-         log.warn("Cannot set attribute when service is started");
-         return;
-      }
-      this.syncChannelName = syncChannelName;
-   }
-
-   public String getAsyncChannelName()
-   {
-      return asyncChannelName;
-   }
-
-   public void setAsyncChannelName(String asyncChannelName)
-   {
-      if (started)
-      {
-         log.warn("Cannot set attribute when service is started");
-         return;
-      }
-      this.asyncChannelName = asyncChannelName;
-   }
-
-   public String getChannelPartitionName()
-   {
-      return channelPartitionName;
-   }
-
-   public void setChannelPartitionName(String channelPartitionName)
-   {
-      if (started)
-      {
-         log.warn("Cannot set attribute when service is started");
-         return;
-      }
-      this.channelPartitionName = channelPartitionName;
-   }
-
-   public void setSyncChannelConfig(Element config) throws Exception
-   {
-      if (started)
-      {
-         log.warn("Cannot set attribute when service is started");
-         return;
-      }
-      syncChannelConfig = config;
-   }
-
-   public Element getSyncChannelConfig()
-   {
-      return syncChannelConfig;
-   }
-
-   public void setAsyncChannelConfig(Element config) throws Exception
-   {
-      if (started)
-      {
-         log.warn("Cannot set attribute when service is started");
-         return;
-      }
-      asyncChannelConfig = config;
-   }
-
-   public Element getAsyncChannelConfig()
-   {
-      return asyncChannelConfig;
-   }
-
-   public void setStateTimeout(long timeout)
-   {
-      if (started)
-      {
-         log.warn("Cannot set attribute when service is started");
-         return;
-      }
-      this.stateTimeout = timeout;
-   }
-
-   public long getStateTimeout()
-   {
-      return stateTimeout;
-   }
-
-   public void setCastTimeout(long timeout)
-   {
-      if (started)
-      {
-         log.warn("Cannot set attribute when service is started");
-         return;
-      }
-      this.castTimeout = timeout;
-   }
-
-   public long getCastTimeout()
-   {
-      return castTimeout;
-   }
-
-   public void setGroupName(String groupName)
-   {
-      this.groupName = groupName;
-   }
-
-   public String getGroupName()
-   {
-      return groupName;
-   }
-
-   public void setStatsSendPeriod(long period)
-   {
-      if (started)
-      {
-         log.warn("Cannot set attribute when service is started");
-         return;
-      }
-      this.statsSendPeriod = period;
-   }
-
-   public long getStatsSendPeriod()
-   {
-      return statsSendPeriod;
-   }
-
-   public String getClusterRouterFactory()
-   {
-      return clusterRouterFactory;
-   }
-
-   public String getMessagePullPolicy()
-   {
-      return messagePullPolicy;
-   }
-
-   public void setClusterRouterFactory(String clusterRouterFactory)
-   {
-      if (started)
-      {
-         log.warn("Cannot set attribute when service is started");
-         return;
-      }
-      this.clusterRouterFactory = clusterRouterFactory;
-   }
-
-   public void setMessagePullPolicy(String messagePullPolicy)
-   {
-      this.messagePullPolicy = messagePullPolicy;
-   }
-
-   public String listBindings()
-   {
-      return postOffice.printBindingInformation();
-   }
-   
-   public int getThreadPoolSize()
-   {
-      return this.threadPoolSize;
-   }
-   
-   public void setThreadPoolSize(int size)
-   {
-      if (started)
-      {
-         log.warn("Cannot set attribute when service is started");
-         return;
-      }
-      this.threadPoolSize = size;
-   }
-
-   // Public --------------------------------------------------------
-
-   // Package protected ---------------------------------------------
-
-   // ServiceMBeanSupport overrides ---------------------------------
-
-   protected synchronized void startService() throws Exception
-   {
-      if (started)
-      {
-         throw new IllegalStateException("Service is already started");
-      }
-
-      super.startService();
-
-      try
-      {
-         TransactionManager tm = getTransactionManagerReference();
-
-         ServerPeer serverPeer = (ServerPeer)server.getAttribute(serverPeerObjectName, "Instance");
-         MessageStore ms = serverPeer.getMessageStore();
-         TransactionRepository tr = serverPeer.getTxRepository();
-         PersistenceManager pm = serverPeer.getPersistenceManagerInstance();
-         int nodeId = serverPeer.getServerPeerID();
-
-         // We don't use Class.forName() since then it won't work with scoped deployments
-         Class clazz = Thread.currentThread().getContextClassLoader().loadClass(messagePullPolicy);
-         
-         MessagePullPolicy pullPolicy = (MessagePullPolicy)clazz.newInstance();
-
-         clazz = Thread.currentThread().getContextClassLoader().loadClass(clusterRouterFactory);
-         
-         ClusterRouterFactory rf = (ClusterRouterFactory)clazz.newInstance();
-
-         ConditionFactory cf = new JMSConditionFactory();
-                  
-         FilterFactory ff = new SelectorFactory();
-         FailoverMapper mapper = new DefaultFailoverMapper();
-
-         JChannelFactory jChannelFactory = null;
-
-         if (channelFactoryName != null)
-         {
-            Object info = null;
-            try
-            {
-               info = server.getMBeanInfo(channelFactoryName);
-            }
-            catch (Exception e)
-            {
-               // log.error("Error", e);
-               // noop... means we couldn't find the channel hence we should use regular
-               // XMLChannelFactories
-            }
-
-            if (info != null)
-            {
-               log.debug(this + " uses MultiplexerJChannelFactory");
-
-               jChannelFactory =
-                  new MultiplexerJChannelFactory(server, channelFactoryName, channelPartitionName,
-                                                 syncChannelName, asyncChannelName);
-            }
-            else
-            {
-               log.debug(this + " uses XMLJChannelFactory");
-               jChannelFactory = new XMLJChannelFactory(syncChannelConfig, asyncChannelConfig);
-            }
-         }
-         else
-         {
-            log.debug(this + " uses XMLJChannelFactory");
-            jChannelFactory = new XMLJChannelFactory(syncChannelConfig, asyncChannelConfig);
-         }
-
-         postOffice =  new DefaultClusteredPostOffice(ds, tm, sqlProperties,
-                                                      createTablesOnStartup,
-                                                      nodeId, officeName, ms,
-                                                      pm, tr, ff, cf,
-                                                      groupName,
-                                                      jChannelFactory,
-                                                      stateTimeout, castTimeout,
-                                                      pullPolicy, rf,
-                                                      mapper,
-                                                      statsSendPeriod,
-                                                      threadPoolSize);
-
-         postOffice.start();
-
-         started = true;
-      }
-      catch (Throwable t)
-      {
-         throw ExceptionUtil.handleJMXInvocation(t, this + " startService");
-      }
-   }
-
-   protected void stopService() throws Exception
-   {
-      if (!started)
-      {
-         throw new IllegalStateException("Service is not started");
-      }
-
-      super.stopService();
-
-      try
-      {
-         postOffice.stop();
-
-         postOffice = null;
-
-         started = false;
-
-         log.debug(this + " stopped");
-      }
-      catch (Throwable t)
-      {
-         throw ExceptionUtil.handleJMXInvocation(t, this + " startService");
-      }
-   }
-
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-
-}
-

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/DefaultPostOfficeService.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/DefaultPostOfficeService.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/DefaultPostOfficeService.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,178 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin;
-
-import javax.management.ObjectName;
-import javax.transaction.TransactionManager;
-
-import org.jboss.jms.server.JMSConditionFactory;
-import org.jboss.jms.server.ServerPeer;
-import org.jboss.jms.server.selector.SelectorFactory;
-import org.jboss.messaging.core.FilterFactory;
-import org.jboss.messaging.core.plugin.contract.ConditionFactory;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.plugin.postoffice.DefaultPostOffice;
-import org.jboss.messaging.core.tx.TransactionRepository;
-import org.jboss.messaging.util.ExceptionUtil;
-
-/**
- * A DefaultPostOfficeService
- * 
- * MBean wrapper for a simple post office
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public class DefaultPostOfficeService extends JDBCServiceSupport
-{
-   private DefaultPostOffice postOffice;
-   
-   private ObjectName serverPeerObjectName;
-   
-   private String officeName;
-   
-   private boolean started;
-   
-   // Constructor ----------------------------------------------------------
-   
-   public DefaultPostOfficeService()
-   {      
-   }
-   
-   // ServerPlugin implementation ------------------------------------------
-   
-   public MessagingComponent getInstance()
-   {
-      return postOffice;
-   }
-   
-   // MBean attributes -----------------------------------------------------
-   
-   public synchronized ObjectName getServerPeer()
-   {
-      return serverPeerObjectName;
-   }
-   
-   public synchronized void setServerPeer(ObjectName on)
-   {
-      if (started)
-      {
-         log.warn("Cannot set attribute when service is started");
-         return;
-      }
-      this.serverPeerObjectName = on;
-   }
-   
-   public synchronized String getPostOfficeName()
-   {
-      return officeName;
-   }
-   
-   public synchronized void setPostOfficeName(String name)
-   {
-      if (started)
-      {
-         log.warn("Cannot set attribute when service is started");
-         return;
-      }
-      this.officeName = name;
-   }
-
-    public String listBindings()
-    {
-        return postOffice.printBindingInformation();
-    }
-
-   
-   // ServiceMBeanSupport overrides ---------------------------------
-   
-   protected synchronized void startService() throws Exception
-   {
-      if (started)
-      {
-         throw new IllegalStateException("Service is already started");
-      }
-      
-      super.startService();
-      
-      try
-      {  
-         TransactionManager tm = getTransactionManagerReference();
-         
-         ServerPeer serverPeer = (ServerPeer)server.getAttribute(serverPeerObjectName, "Instance");
-         
-         MessageStore ms = serverPeer.getMessageStore();
-         
-         PersistenceManager pm = serverPeer.getPersistenceManagerInstance();
-         
-         TransactionRepository tr = serverPeer.getTxRepository();
-         
-         int nodeId = serverPeer.getServerPeerID();
-         
-         FilterFactory ff = new SelectorFactory();
-         
-         ConditionFactory cf = new JMSConditionFactory();
-               
-         postOffice = new DefaultPostOffice(ds, tm, sqlProperties,
-                                         createTablesOnStartup,
-                                         nodeId, officeName, ms, pm, tr, ff, cf);
-         
-         postOffice.start();
-         
-         started = true;         
-      }
-      catch (Throwable t)
-      {
-         throw ExceptionUtil.handleJMXInvocation(t, this + " startService");
-      } 
-   }
-   
-   protected void stopService() throws Exception
-   {
-      if (!started)
-      {
-         throw new IllegalStateException("Service is not started");
-      }
-      
-      super.stopService();
-      
-      try
-      {      
-         postOffice.stop();
-         
-         postOffice = null;
-               
-         started = false;
-                     
-         log.debug(this + " stopped");
-      }
-      catch (Throwable t)
-      {
-         throw ExceptionUtil.handleJMXInvocation(t, this + " startService");
-      } 
-   }      
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/IDManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/IDManager.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/IDManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,139 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.messaging.core.plugin;
-
-import org.jboss.jms.delegate.IDBlock;
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-
-/**
- * 
- * A IDManager.
- * 
- * @author <a href="tim.fox at jboss.com">Tim Fox</a>
- * @author <a href="ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class IDManager implements MessagingComponent
-{
-   // Constants -----------------------------------------------------
-
-   private static final Logger log = Logger.getLogger(IDManager.class);
-
-   // Static --------------------------------------------------------
-
-   // Attributes ----------------------------------------------------
-
-   private boolean trace = log.isTraceEnabled();
-
-   private boolean started;
-
-   private String counterName;
-
-   private int bigBlockSize;
-   private long high;
-   private long low;
-
-   private PersistenceManager pm;
-
-   // Constructors --------------------------------------------------
-
-   public IDManager(String counterName, int bigBlockSize, PersistenceManager pm) throws Exception
-   {
-      this.counterName = counterName;
-      this.bigBlockSize = bigBlockSize;
-      this.pm = pm;
-   }
-
-   // MessagingComponent implementation -----------------------------
-
-   public synchronized void start() throws Exception
-   {
-      getNextBigBlock();
-      started = true;
-   }
-
-   public synchronized void stop() throws Exception
-   {
-      started = false;
-   }
-
-   // Public --------------------------------------------------------
-
-   protected void getNextBigBlock() throws Exception
-   {
-      low = pm.reserveIDBlock(counterName, bigBlockSize);
-      high = low + bigBlockSize - 1;
-      if (trace) { log.trace(this + " retrieved next block of size " + bigBlockSize + " from PersistenceManager, starting at " + low); }
-   }
-
-   public synchronized IDBlock getIDBlock(int size) throws Exception
-   {
-      if (!started)
-      {
-         throw new IllegalStateException(this + " is not started");
-      }
-
-      if (size <= 0)
-      {
-         throw new IllegalArgumentException("block size must be > 0");
-      }
-
-      if (size > bigBlockSize)
-      {
-         throw new IllegalArgumentException("block size must be <= bigBlockSize");
-      }
-
-      if (size > high - low + 1)
-      {
-         getNextBigBlock();
-      }
-
-      long low = this.low;
-
-      this.low += size;
-
-      return new IDBlock(low, this.low - 1);
-   }
-
-   public synchronized long getID() throws Exception
-   {
-      return getIDBlock(1).getLow();
-   }
-
-   public String toString()
-   {
-      return "IDManager[" + counterName + ", " + low + "-" + high + "]";
-   }
-
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/JDBCMBeanSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/JDBCMBeanSupport.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/JDBCMBeanSupport.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,181 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Properties;
-
-import javax.management.MBeanServerInvocationHandler;
-import javax.management.ObjectName;
-import javax.naming.InitialContext;
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
-
-import org.jboss.messaging.util.ExceptionUtil;
-import org.jboss.system.ServiceMBeanSupport;
-import org.jboss.tm.TransactionManagerServiceMBean;
-
-/**
- * A JDBCMBeanSupport
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public class JDBCMBeanSupport extends ServiceMBeanSupport
-{
-   protected DataSource ds;
-   
-   protected Properties sqlProperties;
-         
-   protected TransactionManager tm;
-      
-   private String dataSourceJNDIName;
-   
-   private boolean createTablesOnStartup = true;
-   
-   private ObjectName tmObjectName;
-     
-   public JDBCMBeanSupport()
-   {
-      sqlProperties = new Properties();
-   }   
-   
-   // 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!");
-         }
-         
-         log.debug(this + " started");
-         
-         tm = getTransactionManagerReference();
-      }
-      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 ----------------------------------------------------------     
-   
-   // Private ----------------------------------------------------------------
-   
-   private TransactionManager getTransactionManagerReference()
-   {
-      // lazy initialization
-      if (tm == null)
-      {
-         TransactionManagerServiceMBean tms =
-            (TransactionManagerServiceMBean)MBeanServerInvocationHandler.
-            newProxyInstance(getServer(), tmObjectName, TransactionManagerServiceMBean.class, false);
-
-         tm = tms.getTransactionManager();
-      }
-
-      return tm;
-   }
-           
-   // Innner classes ---------------------------------------------------------   
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManager.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,3216 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.InputStream;
-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.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
-import javax.transaction.xa.Xid;
-
-import org.jboss.jms.tx.MessagingXid;
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageFactory;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.message.MessageSupport;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.tx.PreparedTxInfo;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.messaging.core.tx.TxCallback;
-import org.jboss.messaging.util.JDBCUtil;
-import org.jboss.messaging.util.StreamUtils;
-import org.jboss.messaging.util.Util;
-
-/**
- * JDBC implementation of PersistenceManager.
- *  
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
- * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
- *
- * @version <tt>1.1</tt>
- *
- * JDBCPersistenceManager.java,v 1.1 2006/02/22 17:33:41 timfox Exp
- */
-public class JDBCPersistenceManager extends JDBCSupport implements PersistenceManager
-{
-   // Constants -----------------------------------------------------
-   
-   private static final Logger log = Logger.getLogger(JDBCPersistenceManager.class); 
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-   
-   private boolean trace = log.isTraceEnabled();
-      
-   private boolean usingBatchUpdates = false;
-   
-   private boolean usingBinaryStream = true;
-   
-   private boolean usingTrailingByte = false;
-   
-   private int maxParams;
-   
-   private short orderCount;
-   
-   
-   // Constructors --------------------------------------------------
-    
-   public JDBCPersistenceManager(DataSource ds, TransactionManager tm, Properties sqlProperties,
-                                 boolean createTablesOnStartup, boolean usingBatchUpdates,
-                                 boolean usingBinaryStream, boolean usingTrailingByte, int maxParams)
-   {
-      super(ds, tm, sqlProperties, createTablesOnStartup);
-      
-      this.usingBatchUpdates = usingBatchUpdates;
-      
-      this.usingBinaryStream = usingBinaryStream;
-      
-      this.usingTrailingByte = usingTrailingByte;
-      
-      this.maxParams = maxParams;      
-   }
-   
-   
-   // MessagingComponent overrides ---------------------------------
-   
-   public void start() throws Exception
-   {
-      super.start();
-
-      Connection conn = null;
-
-      TransactionWrapper wrap = new TransactionWrapper();
-
-      try
-      {
-         conn = ds.getConnection();      
-         //JBossMessaging requires transaction isolation of READ_COMMITTED
-         //Any looser isolation level and we cannot maintain consistency for paging (HSQL)
-         if (conn.getTransactionIsolation() != Connection.TRANSACTION_READ_COMMITTED)
-         {
-            int level = conn.getTransactionIsolation();
-
-            String warn =
-               "\n\n" +
-               "JBoss Messaging Warning: DataSource connection transaction isolation should be READ_COMMITTED, but it is currently " + Util.transactionIsolationToString(level) + ".\n" +
-               "                         Using an isolation level less strict than READ_COMMITTED may lead to data consistency problems.\n" +
-               "                         Using an isolation level more strict than READ_COMMITTED may lead to deadlock.\n";
-            log.warn(warn);
-         }
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-         if (conn != null)
-         {
-            conn.close();
-         }
-         wrap.end();
-      }
-             
-      log.debug(this + " started");
-   }
-   
-   public void stop() throws Exception
-   {
-      super.stop();
-   }
-   
-   // PersistenceManager implementation -------------------------
-   
-   // Related to XA Recovery
-   // ======================
-   
-   public List getMessageChannelPairRefsForTx(long transactionId) throws Exception
-   {
-      String sql = this.getSQLStatement("SELECT_MESSAGE_ID_FOR_REF");
-      return getMessageChannelPair(sql, transactionId);
-   }
-   
-   public List getMessageChannelPairAcksForTx(long transactionId) throws Exception
-   {
-      String sql = this.getSQLStatement("SELECT_MESSAGE_ID_FOR_ACK");
-      return getMessageChannelPair(sql, transactionId);
-   }
-   
-   public List retrievePreparedTransactions() throws Exception
-   {
-      /* Note the API change for 1.0.2 XA Recovery -- List now contains instances of PreparedTxInfo<TxId, Xid>
-       * instead of direct Xids [JPL] */
-      
-      Connection conn = null;
-      Statement st = null;
-      ResultSet rs = null;
-      PreparedTxInfo txInfo = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-      
-      try
-      {
-         List transactions = new ArrayList();
-         
-         conn = ds.getConnection();
-         
-         st = conn.createStatement();
-         
-         String sql = this.getSQLStatement("SELECT_PREPARED_TRANSACTIONS");
-         
-         rs = st.executeQuery(sql);
-         
-         while (rs.next())
-         {
-            //get the existing tx id --MK START
-            long txId = rs.getLong(1);
-            
-            byte[] branchQual = getVarBinaryColumn(rs, 2);
-            
-            int formatId = rs.getInt(3);
-            
-            byte[] globalTxId = getVarBinaryColumn(rs, 4);
-            
-            Xid xid = new MessagingXid(branchQual, formatId, globalTxId);
-            
-            // create a tx info object with the result set detailsdetails
-            txInfo = new PreparedTxInfo(txId, xid);
-            
-            transactions.add(txInfo);
-         }
-         
-         return transactions;
-         
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeResultSet(rs);
-      	closeStatement(st);
-      	closeConnection(conn);
-         wrap.end();
-      }
-   }
-         
-               
-   // Related to counters
-   // ===================
-   
-   public long reserveIDBlock(String counterName, int size) throws Exception
-   {
-      if (trace) { log.trace("Getting ID block for counter " + counterName + ", size " + size); }
-      
-      if (size <= 0)
-      {
-         throw new IllegalArgumentException("block size must be > 0");
-      }
-      
-      Connection conn = null;
-      PreparedStatement ps = null;
-      ResultSet rs = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-      
-      try
-      {
-         conn = ds.getConnection();
-
-         //For the clustered case - this MUST use SELECT .. FOR UPDATE or a similar
-         //construct the locks the row
-         String selectCounterSQL = getSQLStatement("SELECT_COUNTER");
-         
-         ps = conn.prepareStatement(selectCounterSQL);
-         
-         ps.setString(1, counterName);
-         
-         rs = ps.executeQuery();
-         
-         if (trace) { log.trace(JDBCUtil.statementToString(selectCounterSQL, counterName)); }         
-         
-         if (!rs.next())
-         {
-            rs.close();
-            rs = null;
-            
-            ps.close();
-            
-            //There is a very small possibility that two threads will attempt to insert the same counter
-            //at the same time, if so, then the second one will fail eventually after a few retries by throwing
-            //a primary key violation.
-            
-            String insertCounterSQL = getSQLStatement("INSERT_COUNTER");
-            
-            ps = conn.prepareStatement(insertCounterSQL);
-            
-            ps.setString(1, counterName);
-            ps.setLong(2, size);
-            
-            int rows = updateWithRetry(ps);
-            if (trace) { log.trace(JDBCUtil.statementToString(insertCounterSQL, counterName, new Integer(size)) + " inserted " + rows + " rows"); }
-            
-            ps.close();            
-            ps = null;
-            return 0;
-         }
-         
-         long nextId = rs.getLong(1);
-         
-         rs.close();
-         rs = null;
-         
-         ps.close();
-
-         String updateCounterSQL = getSQLStatement("UPDATE_COUNTER");
-
-         ps = conn.prepareStatement(updateCounterSQL);
-         
-         ps.setLong(1, nextId + size);
-         ps.setString(2, counterName);
-         
-         int rows = updateWithRetry(ps);
-         if (trace) { log.trace(JDBCUtil.statementToString(updateCounterSQL, new Long(nextId + size), counterName) + " updated " + rows + " rows"); }
-         
-         return nextId;
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeStatement(ps);
-      	closeConnection(conn);
-         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
-    * with a maximum of 100 elements.
-    * If there are more than maxParams message to retrieve this is repeated a number of times.
-    * For "Enterprise" databases (Oracle, DB2, Sybase etc) a more sophisticated technique should be used
-    * e.g. Oracle ARRAY types in Oracle which can be submitted as a param to an Oracle prepared statement
-    * Although this would all be DB specific.
-    */
-   public List getMessages(List messageIds) throws Exception
-   {
-      if (trace) { log.trace("Getting batch of messages for " + messageIds); }
-      
-      Connection conn = null;
-      PreparedStatement ps = null;
-      ResultSet rs = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-      
-      try
-      {
-         conn = ds.getConnection();
-         
-         Iterator iter = messageIds.iterator();
-         
-         int size = messageIds.size();
-         
-         int count = 0;
-         
-         List msgs = new ArrayList();
-         
-         while (iter.hasNext())
-         {
-            if (ps == null)
-            {
-               //PreparedStatements are cached in the JCA layer so we will never actually have more than
-               //100 distinct ones            
-               int numParams;
-               if (count < (size / maxParams) * maxParams)
-               {
-                  numParams = maxParams;
-               }
-               else
-               {
-                  numParams = size % maxParams;
-               }
-               StringBuffer buff = new StringBuffer(getSQLStatement("LOAD_MESSAGES"));
-               buff.append(" WHERE ").append(getSQLStatement("MESSAGE_ID_COLUMN")).append(" IN (");
-               for (int i = 0; i < numParams; i++)
-               {
-                  buff.append("?");
-                  if (i < numParams - 1)
-                  {
-                     buff.append(",");
-                  }
-               }
-               buff.append(")");
-               ps = conn.prepareStatement(buff.toString());
-               
-               if (trace)
-               {
-                  log.trace(buff.toString());
-               }
-            }
-            
-            long msgId = ((Long)iter.next()).longValue();
-            
-            ps.setLong((count % maxParams) + 1, msgId);
-            
-            count++;
-            
-            if (!iter.hasNext() || count % maxParams == 0)
-            {
-               rs = ps.executeQuery();
-               
-               while (rs.next())
-               {       
-                  long messageId = rs.getLong(1);
-                  
-                  boolean reliable = rs.getString(2).equals("Y");
-                  
-                  long expiration = rs.getLong(3);
-                  
-                  long timestamp = rs.getLong(4);
-                  
-                  byte priority = rs.getByte(5);        
-                  
-                  byte[] bytes = getBytes(rs, 6);
-                  
-                  HashMap headers = bytesToMap(bytes);
-                  
-                  byte[] payload = getBytes(rs, 7);
-                  
-                  byte type = rs.getByte(8);
-                  
-                  Message m = MessageFactory.createMessage(messageId, reliable, expiration, timestamp, priority,
-                                                           headers, payload, type);
-                  msgs.add(m);
-               }
-               
-               rs.close();
-               rs = null;
-               
-               ps.close();
-               ps = null;
-            }
-         }
-         
-         if (trace) { log.trace("Loaded " + msgs.size() + " messages in total"); }
-
-         return msgs;
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeResultSet(rs);
-      	closeStatement(ps);
-      	closeConnection(conn);
-         wrap.end();
-      }
-   }  
-   
-       
-   // Related to paging functionality
-   // ===============================                 
-   
-   public void pageReferences(long channelID, List references, boolean paged) throws Exception
-   {  
-      Connection conn = null;
-      PreparedStatement psInsertReference = null;  
-      PreparedStatement psInsertMessage = null;
-      PreparedStatement psUpdateMessage = null;
-      PreparedStatement psMessageExists = null;
-      ResultSet rsMessageExists = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-            
-      //First we order the references in message order
-      orderReferences(references);
-                         
-      try
-      {
-         //Now we get a lock on all the messages. Since we have ordered the refs we should avoid deadlock
-         getLocks(references);
-         
-         conn = ds.getConnection();
-         
-         Iterator iter = references.iterator();
-         
-         boolean messageInsertsInBatch = false;
-         boolean messageUpdatesInBatch = false;
-         
-         if (usingBatchUpdates)
-         {
-            psInsertReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
-            psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
-            psUpdateMessage = conn.prepareStatement(getSQLStatement("INC_CHANNEL_COUNT"));
-         }
-         
-         while (iter.hasNext())
-         {
-            //We may need to persist the message itself 
-            MessageReference ref = (MessageReference) iter.next();
-                                            
-            //For non reliable refs we insert the ref (and maybe the message) itself
-                           
-            if (!usingBatchUpdates)
-            {
-               psInsertReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
-            }
-            
-            //Now store the reference
-            addReference(channelID, ref, psInsertReference, paged);
-                        
-            if (usingBatchUpdates)
-            {
-               psInsertReference.addBatch();
-            }
-            else
-            {
-               int rows = updateWithRetry(psInsertReference);
-               
-               if (trace)
-               {
-                  log.trace("Inserted " + rows + " rows");
-               }
-               
-               psInsertReference.close();
-               psInsertReference = null;
-            }
-            
-            if (!usingBatchUpdates)
-            {
-               psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
-               psUpdateMessage = conn.prepareStatement(getSQLStatement("INC_CHANNEL_COUNT"));
-            }
-                                                                                     
-            //Maybe we need to persist the message itself
-            Message m = ref.getMessage();
-            
-            //In a paging situation, we cannot use the persisted flag on the message to determine whether
-            //to insert the message or not.
-            //This is because a channel (possibly on another node) may be paging too and referencing
-            //the same message, and might have removed the message independently, the other
-            //channel will not know about this.
-            //Therefore we have to check if the message is already in the database and insert it if it isn't
-            
-            //TODO This is a bit of a hassle -
-            //A cleaner and better solution here is to completely separate out the paging functionality from the
-            //standard persistence functionality since it complicates things considerably.
-            //We should define a paging store which is separate from the persistence store, and
-            //typically not using the database for the paging store - probably use a file based store
-            //e.g HOWL or some other logger
-            
-            //Note when running this with two or more competing channels in the same process, then
-            //we do not need a FOR UPDATE on the select since we lock the messages in memory
-            //However for competing nodes, we do, therefore we require a database that supports
-            //this, this is another reason why we cannot use HSQL in a clustered environment
-            //since it does not have a for update equivalent
-            
-            boolean added;
-            
-            psMessageExists = conn.prepareStatement(getSQLStatement("MESSAGE_EXISTS"));
-            
-            psMessageExists.setLong(1, m.getMessageID());
-            
-            rsMessageExists = psMessageExists.executeQuery();
-             
-            if (rsMessageExists.next())
-            {
-               //Message exists
-               
-               // Update the message with the new channel count
-               incrementChannelCount(m, psUpdateMessage);
-                  
-               added = false;              
-            }
-            else
-            {
-               //Hasn't been persisted before so need to persist the message
-               storeMessage(m, psInsertMessage);
-               
-               added = true;
-            }    
-            
-            if (usingBatchUpdates)
-            {
-               if (added)
-               {
-                  psInsertMessage.addBatch();
-                  messageInsertsInBatch = true;
-               }
-               else
-               {
-                  psUpdateMessage.addBatch();
-                  messageUpdatesInBatch = true;
-               }
-            }
-            else
-            {
-               if (added)
-               {
-                  int rows = updateWithRetry(psInsertMessage);
-                                      
-                  if (trace)
-                  {
-                     log.trace("Inserted " + rows + " rows");
-                  }
-               }
-               else
-               {               
-                  int rows = updateWithRetry(psUpdateMessage);
-                  
-                  if (trace)
-                  {
-                     log.trace("Updated " + rows + " rows");
-                  }
-               }
-               psInsertMessage.close();
-               psInsertMessage = null;
-               psUpdateMessage.close();
-               psUpdateMessage = null;
-            }      
-         }         
-         
-         if (usingBatchUpdates)
-         {
-            int[] rowsReference = updateWithRetryBatch(psInsertReference);
-            
-            if (trace) { logBatchUpdate(getSQLStatement("INSERT_MESSAGE_REF"), rowsReference, "inserted"); }
-            
-            if (messageInsertsInBatch)
-            {
-               int[] rowsMessage = updateWithRetryBatch(psInsertMessage);
-               
-               if (trace) { logBatchUpdate(getSQLStatement("INSERT_MESSAGE"), rowsMessage, "inserted"); }
-            }
-            if (messageUpdatesInBatch)
-            {
-               int[] rowsMessage = updateWithRetryBatch(psUpdateMessage);
-               
-               if (trace) { logBatchUpdate(getSQLStatement("INC_CHANNEL_COUNT"), rowsMessage, "updated"); }
-            }
-            
-            psInsertReference.close();
-            psInsertReference = null;
-            psInsertMessage.close();
-            psInsertMessage = null;
-            psUpdateMessage.close();
-            psUpdateMessage = null;
-         }        
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeStatement(psInsertReference);
-      	closeStatement(psInsertMessage);
-      	closeStatement(psUpdateMessage);
-      	closeConnection(conn);         
-         try
-         {
-            wrap.end();                       
-         }
-         finally
-         {            
-            //And then release locks
-            this.releaseLocks(references);
-         }         
-      }      
-   }
-         
-   public void removeDepagedReferences(long channelID, List references) throws Exception
-   {
-      if (trace) { log.trace(this + " Removing " + references.size() + " refs from channel " + channelID); }
-          
-      Connection conn = null;
-      PreparedStatement psDeleteReference = null;  
-      PreparedStatement psDeleteMessage = null;
-      PreparedStatement psUpdateMessage = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-        
-      //We order the references
-      orderReferences(references);
-             
-      try
-      {
-         //We get locks on all the messages - since they are ordered we avoid deadlock
-         getLocks(references);
-         
-         conn = ds.getConnection();
-         
-         Iterator iter = references.iterator();
-         
-         if (usingBatchUpdates)
-         {
-            psDeleteReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
-            psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
-            psUpdateMessage = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
-         }
-         
-         while (iter.hasNext())
-         {
-            MessageReference ref = (MessageReference) iter.next();
-                                                             
-            if (!usingBatchUpdates)
-            {
-               psDeleteReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
-            }
-            
-            removeReference(channelID, ref, psDeleteReference);
-            
-            if (usingBatchUpdates)
-            {
-               psDeleteReference.addBatch();
-            }
-            else
-            {
-               int rows = updateWithRetry(psDeleteReference);
-               
-               if (trace) { log.trace("Deleted " + rows + " rows"); }
-               
-               psDeleteReference.close();
-               psDeleteReference = null;
-            }
-            
-            if (!usingBatchUpdates)
-            {
-               psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
-               psUpdateMessage = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
-            }
-               
-            Message m = ref.getMessage();
-                                    
-            //Maybe we need to delete the message itself
-              
-            //Update the message with the new channel count
-            decrementChannelCount(m, psUpdateMessage);
-            
-
-            //Run the remove message update
-            removeMessage(m, psDeleteMessage);
-                        
-            if (usingBatchUpdates)
-            {
-               psUpdateMessage.addBatch();
-               
-               psDeleteMessage.addBatch();
-            }
-            else
-            {  
-               int rows = updateWithRetry(psUpdateMessage);
-                                                 
-               if (trace) { log.trace("Updated " + rows + " rows"); }
-               
-               rows = updateWithRetry(psDeleteMessage);
-        
-               if (trace) { log.trace("Deleted " + rows + " rows"); }
-            
-               psDeleteMessage.close();
-               psDeleteMessage = null;
-               psUpdateMessage.close();
-               psUpdateMessage = null;
-            }  
-            
-         }         
-         
-         if (usingBatchUpdates)
-         {
-            int[] rowsReference = updateWithRetryBatch(psDeleteReference);
-            
-            if (trace) { logBatchUpdate(getSQLStatement("DELETE_MESSAGE_REF"), rowsReference, "deleted"); }
-            
-            rowsReference = updateWithRetryBatch(psUpdateMessage);
-            
-            if (trace) { logBatchUpdate(getSQLStatement("DEC_CHANNEL_COUNT"), rowsReference, "updated"); }
-            
-            rowsReference = updateWithRetryBatch(psDeleteMessage);
-            
-            if (trace) { logBatchUpdate(getSQLStatement("DELETE_MESSAGE"), rowsReference, "deleted"); }
-                                    
-            psDeleteReference.close();
-            psDeleteReference = null;
-            psDeleteMessage.close();
-            psDeleteMessage = null;
-            psUpdateMessage.close();
-            psUpdateMessage = null;
-         }              
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeStatement(psDeleteReference);
-      	closeStatement(psDeleteMessage);
-      	closeStatement(psUpdateMessage);
-      	closeConnection(conn);         
-         try
-         {
-            wrap.end();
-         }
-         finally
-         {     
-            //And then release locks
-            this.releaseLocks(references);
-         }         
-      }      
-   }
-   
-   public void updateReferencesNotPagedInRange(long channelID, long orderStart, long orderEnd, long num) throws Exception
-   {
-      if (trace) { log.trace("Updating paaged references for channel " + channelID + " between " + orderStart + " and " + orderEnd); }
-      
-      Connection conn = null;
-      PreparedStatement ps = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-    
-      try
-      {
-         conn = ds.getConnection();
-         
-         ps = conn.prepareStatement(getSQLStatement("UPDATE_REFS_NOT_PAGED"));
-                 
-         ps.setLong(1, orderStart);
-         
-         ps.setLong(2, orderEnd);
-         
-         ps.setLong(3, channelID);
-         
-         int rows = updateWithRetry(ps);
-           
-         if (trace) { log.trace(JDBCUtil.statementToString(getSQLStatement("UPDATE_REFS_NOT_PAGED"), new Long(channelID),
-                                new Long(orderStart), new Long(orderEnd)) + " updated " + rows + " rows"); }
-
-         //Sanity check
-         if (rows != num)
-         {
-            throw new IllegalStateException("Did not update correct number of rows");
-         }            
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeStatement(ps);
-      	closeConnection(conn);       
-         wrap.end();
-      }
-   }
-   
-   public InitialLoadInfo mergeAndLoad(long fromChannelID, long toChannelID, int numberToLoad, long firstPagingOrder, long nextPagingOrder) throws Exception
-   {
-      if (trace) { log.trace("Merging channel from " + fromChannelID + " to " + toChannelID + " numberToLoad:" + numberToLoad + " firstPagingOrder:" + firstPagingOrder + " nextPagingOrder:" + nextPagingOrder); }
-      
-      Connection conn = null;
-      PreparedStatement ps = null;
-      ResultSet rs = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-      PreparedStatement ps2 = null;
-    
-      try
-      {
-         conn = ds.getConnection();
-         
-         /*
-          * If channel is paging and has full size f
-          * 
-          * then we don't need to load any refs but we need to:
-          * 
-          * make sure the page ord is correct across the old paged and new refs
-          * 
-          * we know the max page ord (from the channel) for the old refs so we just need to:
-          * 
-          * 1) Iterate through the failed channel and update page_ord = max + 1, max + 2 etc
-          * 
-          * 2) update channel id
-          * 
-          * 
-          * If channel is not paging and the total refs before and after <=f
-          * 
-          * 1) Load all refs from failed channel
-          * 
-          * 2) Update channel id
-          * 
-          * return those refs
-          * 
-          * 
-          * If channel is not paging but total new refs > f
-          * 
-          * 1) Iterate through failed channel refs and take the first x to make the channel full
-          * 
-          * 2) Update the others with page_ord starting at zero 
-          * 
-          * 3) Update channel id
-          * 
-          * In general:
-          * 
-          * We have number to load n, max page size p
-          * 
-          * 1) Iterate through failed channel refs in page_ord order
-          * 
-          * 2) Put the first n in a List.
-          * 
-          * 3) Initialise page_ord_count to be p or 0 depending on whether it was specified
-          * 
-          * 4) Update the page_ord of the remaining refs accordiningly
-          * 
-          * 5) Update the channel id
-          * 
-          */
-         
-         //First load the refs from the failed channel
-
-         List refs = new ArrayList();
-         
-         ps = conn.prepareStatement(getSQLStatement("LOAD_REFS"));
-         
-         ps.setLong(1, fromChannelID);
-                 
-         rs = ps.executeQuery();
-         
-         int count = 0;
-         
-         boolean arePaged = false;
-         
-         long pageOrd = nextPagingOrder;
-         
-         while (rs.next())
-         {
-            long msgId = rs.getLong(1);            
-            int deliveryCount = rs.getInt(2);
-            long sched = rs.getLong(3);
-            
-            if (count < numberToLoad)
-            {           
-               ReferenceInfo ri = new ReferenceInfo(msgId, deliveryCount, sched);
-               
-               refs.add(ri);
-            }
-            
-            // Set page ord
-            
-            if (ps2 == null)
-            {
-               ps2 = conn.prepareStatement(getSQLStatement("UPDATE_PAGE_ORDER"));
-            }
-                
-            if (count < numberToLoad)
-            {
-               ps2.setNull(1, Types.BIGINT);
-               
-               if (trace) { log.trace("Set page ord to null"); }
-            }
-            else
-            {                                 
-               ps2.setLong(1, pageOrd);
-               
-               if (trace) { log.trace("Set page ord to " + pageOrd); }
-               
-               arePaged = true; 
-               
-               pageOrd++;                      
-            }
-            
-            ps2.setLong(2, msgId);
-            
-            ps2.setLong(3, fromChannelID);
-            
-            int rows = updateWithRetry(ps2);
-            
-            if (trace) { log.trace("Update page ord updated " + rows + " rows"); }
-
-            count++;            
-         }
-         
-         ps.close();
-         
-         // Now swap the channel id
-         
-         ps = conn.prepareStatement(getSQLStatement("UPDATE_CHANNEL_ID"));
-         
-         ps.setLong(1, toChannelID);
-         
-         ps.setLong(2, fromChannelID);
-         
-         int rows = updateWithRetry(ps);
-         
-         if (trace) { log.trace("Update channel id updated " + rows + " rows"); }
-                           
-         if (arePaged)
-         {            
-            return new InitialLoadInfo(new Long(firstPagingOrder), new Long(pageOrd - 1), refs);
-         }
-         else
-         {
-            return new InitialLoadInfo(null, null, refs);
-         }         
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeStatement(ps);
-      	closeStatement(ps2);
-      	closeConnection(conn);       
-         wrap.end();
-      }
-   }
-   
-   public void updatePageOrder(long channelID, List references) throws Exception
-   {
-      Connection conn = null;
-      PreparedStatement psUpdateReference = null;  
-      TransactionWrapper wrap = new TransactionWrapper();
-      
-      if (trace) { log.trace("Updating page order for channel:" + channelID); }
-        
-      try
-      {
-         conn = ds.getConnection();
-         
-         Iterator iter = references.iterator();
-         
-         if (usingBatchUpdates)
-         {
-            psUpdateReference = conn.prepareStatement(getSQLStatement("UPDATE_PAGE_ORDER"));
-         }
-         
-         while (iter.hasNext())
-         {
-            MessageReference ref = (MessageReference) iter.next();
-                 
-            if (!usingBatchUpdates)
-            {
-               psUpdateReference = conn.prepareStatement(getSQLStatement("UPDATE_PAGE_ORDER"));
-            }
-            
-            psUpdateReference.setLong(1, ref.getPagingOrder());
-
-            psUpdateReference.setLong(2, ref.getMessage().getMessageID());
-            
-            psUpdateReference.setLong(3, channelID);
-            
-            if (usingBatchUpdates)
-            {
-               psUpdateReference.addBatch();
-            }
-            else
-            {
-               int rows = updateWithRetry(psUpdateReference);
-               
-               if (trace) { log.trace("Updated " + rows + " rows"); }
-               
-               psUpdateReference.close();
-               psUpdateReference = null;
-            }
-         }
-                     
-         if (usingBatchUpdates)
-         {
-            int[] rowsReference = updateWithRetryBatch(psUpdateReference);
-            
-            if (trace) { logBatchUpdate(getSQLStatement("UPDATE_PAGE_ORDER"), rowsReference, "updated"); }
-                        
-            psUpdateReference.close();
-            psUpdateReference = null;
-         }
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeStatement(psUpdateReference);
-      	closeConnection(conn);       
-         wrap.end();
-      }    
-   }
-      
-   public List getPagedReferenceInfos(long channelID, long orderStart, int number) throws Exception
-   {
-      if (trace) { log.trace("loading message reference info for channel " + channelID + " from " + orderStart + " number " + number);      }
-                 
-      List refs = new ArrayList();
-      
-      Connection conn = null;
-      PreparedStatement ps = null;
-      ResultSet rs = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-      
-      try
-      {
-         conn = ds.getConnection();
-         
-         ps = conn.prepareStatement(getSQLStatement("LOAD_PAGED_REFS"));
-         
-         ps.setLong(1, channelID);
-         
-         ps.setLong(2, orderStart);
-         
-         ps.setLong(3, orderStart + number - 1);
-         
-         rs = ps.executeQuery();
-         
-         long ord = orderStart;
-         
-         while (rs.next())
-         {
-            long msgId = rs.getLong(1);     
-            int deliveryCount = rs.getInt(2);
-            int pageOrd = rs.getInt(3);
-            long sched = rs.getLong(4);
-            
-            //Sanity check
-            if (pageOrd != ord)
-            {
-               throw new IllegalStateException("Unexpected pageOrd: " + pageOrd + " expected: " + ord);
-            }
-            
-            ReferenceInfo ri = new ReferenceInfo(msgId, deliveryCount, sched);
-            
-            refs.add(ri);
-            ord++;
-         }
-         
-         //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)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeResultSet(rs);
-      	closeStatement(ps);
-      	closeConnection(conn);       
-         wrap.end();
-      }      
-   }   
-   
-   /*
-    * Load the initial, non paged refs
-    */
-   public InitialLoadInfo loadFromStart(long channelID, int number) throws Exception
-   {
-      if (trace) { log.trace("loading initial reference infos for channel " + channelID);  }
-                    
-      Connection conn = null;
-      PreparedStatement ps = null;
-      ResultSet rs = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-                                
-      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 = new Long(rs.getLong(1));
-         
-         if (rs.wasNull())
-         {
-            minOrdering = null;
-         }
-         
-         Long maxOrdering = new Long(rs.getLong(2));
-         
-         if (rs.wasNull())
-         {
-            maxOrdering = null;
-         }
-         
-         ps.close();
-         
-         conn.close();
-         
-         conn = ds.getConnection();         
-         
-         ps = conn.prepareStatement(getSQLStatement("LOAD_UNPAGED_REFS"));
-         
-         ps.setLong(1, channelID);
-                 
-         rs = ps.executeQuery();
-         
-         List refs = new ArrayList();
-         
-         int count = 0;
-         while (rs.next())
-         {
-            long msgId = rs.getLong(1);            
-            int deliveryCount = rs.getInt(2);
-            long sched = rs.getLong(3);
-            
-            ReferenceInfo ri = new ReferenceInfo(msgId, deliveryCount, sched);
-            
-            if (count < number)
-            {
-               refs.add(ri);
-            }            
-            
-            count++;
-         }
-                  
-         //No refs paged
-            
-         if (count > number)
-         {
-            throw new IllegalStateException("Cannot load channel " + channelID + " since the fullSize parameter is too small to load " +
-                     " all the required references, fullSize needs to be at least " + count + " it is currently " + number);
-         }
-                         
-         return new InitialLoadInfo(minOrdering, maxOrdering, refs);
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeResultSet(rs);
-      	closeStatement(ps);      	
-      	closeConnection(conn);       
-         wrap.end();
-      }      
-   }   
-   
-   
-   // End of paging functionality
-   // ===========================
-   
-   public void addReference(long channelID, MessageReference ref, Transaction tx) throws Exception
-   {      
-      if (tx != null)
-      {
-         //In a tx so we just add the ref in the tx in memory for now
-
-         TransactionCallback callback = getCallback(tx);
-
-         callback.addReferenceToAdd(channelID, ref);
-      }
-      else
-      {         
-         //No tx so add the ref directly in the db
-         
-         TransactionWrapper wrap = new TransactionWrapper();
-         
-         PreparedStatement psReference = null;
-         PreparedStatement psMessage = null;
-         
-         Connection conn = ds.getConnection();
-         
-         Message m = ref.getMessage();     
-           
-         try
-         {            
-            // Get lock on message
-            LockMap.instance.obtainLock(m);
-                                    
-            psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
-            
-            // Add the reference
-            addReference(channelID, ref, psReference, false);
-            
-            int rows = updateWithRetry(psReference);      
-            
-            if (trace) { log.trace("Inserted " + rows + " rows"); }
-              
-            if (!m.isPersisted())
-            {
-               // First time so persist the message
-               psMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
-               
-               storeMessage(m, psMessage);
-               
-               m.setPersisted(true);
-            }
-            else
-            {
-               //Update the message's channel count
-               psMessage = conn.prepareStatement(getSQLStatement("INC_CHANNEL_COUNT"));
-               
-               incrementChannelCount(m, psMessage);
-            }
-                           
-            rows = updateWithRetry(psMessage);
-            
-            if (trace) { log.trace("Inserted/updated " + rows + " rows"); }     
-            
-            log.trace("message Inserted/updated " + rows + " rows");
-         }
-         catch (Exception e)
-         {
-            wrap.exceptionOccurred();
-            throw e;
-         }
-         finally
-         {
-         	closeStatement(psReference);
-         	closeStatement(psMessage);
-         	closeConnection(conn);  
-            try
-            {
-               wrap.end();
-            }
-            finally
-            {   
-               //Release Lock
-               LockMap.instance.releaseLock(m);
-            }
-         }      
-      }
-   }
-   
-   public void updateDeliveryCount(long channelID, MessageReference ref) throws Exception
-   {
-      TransactionWrapper wrap = new TransactionWrapper();
-      
-      PreparedStatement psReference = null;
-      
-      Connection conn = ds.getConnection();
-       
-      try
-      {                                    
-         psReference = conn.prepareStatement(getSQLStatement("UPDATE_DELIVERY_COUNT"));
-         
-         psReference.setInt(1, ref.getDeliveryCount());
-         
-         psReference.setLong(2, channelID);
-         
-         psReference.setLong(3, ref.getMessage().getMessageID());
-         
-         int rows = updateWithRetry(psReference);
-
-         if (trace) { log.trace("Updated " + rows + " rows"); }
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeStatement(psReference);
-      	closeConnection(conn);
-         wrap.end();                        
-      }  
-   }
-   
-   public void removeReference(long channelID, MessageReference ref, Transaction tx) throws Exception
-   {      
-      if (tx != null)
-      {
-         //In a tx so we just add the ref in the tx in memory for now
-
-         TransactionCallback callback = getCallback(tx);
-
-         callback.addReferenceToRemove(channelID, ref);
-      }
-      else
-      {         
-         //No tx so we remove the reference directly from the db
-         
-         TransactionWrapper wrap = new TransactionWrapper();
-         
-         PreparedStatement psReference = null;
-         PreparedStatement psUpdate = null;
-         PreparedStatement psMessage = null;
-         
-         Connection conn = ds.getConnection();
-         
-         Message m = ref.getMessage();         
-         
-         try
-         {
-            //get lock on message
-            LockMap.instance.obtainLock(m);
-                              
-            psReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
-            
-            //Remove the message reference
-            removeReference(channelID, ref, psReference);
-            
-            int rows = updateWithRetry(psReference);
-            
-            if (rows != 1)
-            {
-               log.warn("Failed to remove row for: " + ref);
-               return;
-            }
-            
-            if (trace) { log.trace("Deleted " + rows + " rows"); }
-            
-            //Update the messages channel count
-            
-            psUpdate = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
-            
-            decrementChannelCount(m, psUpdate);
-            
-            rows = updateWithRetry(psUpdate);
-            
-            if (trace) { log.trace("Updated " + rows + " rows"); } 
-            
-            //Delete the message (if necessary)
-            
-            psMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
-            
-            removeMessage(m, psMessage);
-                       
-            rows = updateWithRetry(psMessage);
-            
-            if (trace) { log.trace("Delete " + rows + " rows"); }                           
-         }
-         catch (Exception e)
-         {
-            wrap.exceptionOccurred();
-            throw e;
-         }
-         finally
-         {
-         	closeStatement(psReference);
-         	closeStatement(psUpdate);
-         	closeStatement(psMessage);
-         	closeConnection(conn);
-            try
-            {
-               wrap.end();               
-            }
-            finally
-            {      
-               //release the lock
-               LockMap.instance.releaseLock(m);
-            }
-         }      
-      }
-   }
-   
-           
-   public boolean referenceExists(long channelID, long messageID) throws Exception
-   {
-      Connection conn = null;
-      PreparedStatement st = null;
-      ResultSet rs = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-
-      try
-      {
-         conn = ds.getConnection();
-
-         st = conn.prepareStatement(getSQLStatement("SELECT_EXISTS_REF"));
-         st.setLong(1, channelID);
-         st.setLong(2, messageID);
-
-         rs = st.executeQuery();
-
-         if (rs.next())
-         {
-            return true;
-         }
-         else
-         {
-            return false;
-         }
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeResultSet(rs);
-      	closeStatement(st);
-      	closeConnection(conn);
-         wrap.end();
-      }
-   }
-
-   public boolean referenceExists(long messageID) throws Exception
-   {
-      Connection conn = null;
-      PreparedStatement st = null;
-      ResultSet rs = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-
-      try
-      {
-         conn = ds.getConnection();
-
-         st = conn.prepareStatement(getSQLStatement("SELECT_EXISTS_REF_MESSAGE_ID"));
-         st.setLong(1, messageID);
-
-         rs = st.executeQuery();
-
-         if (rs.next())
-         {
-            return true;
-         }
-         else
-         {
-            return false;
-         }
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeResultSet(rs);
-      	closeStatement(st);
-      	closeConnection(conn);
-         wrap.end();
-      }
-   }
-
-   // Public --------------------------------------------------------
-   
-   public String toString()
-   {
-      return "JDBCPersistenceManager[" + Integer.toHexString(hashCode()) + "]";
-   }   
-   
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-      
-   protected TransactionCallback getCallback(Transaction tx)
-   {
-      TransactionCallback callback = (TransactionCallback) tx.getCallback(this);
-
-      if (callback == null)
-      {
-         callback = new TransactionCallback(tx);
-
-         tx.addCallback(callback, this);
-      }
-
-      return callback;
-   }
-   
-   /**
-    * We order the list of references in ascending message order thus preventing deadlock when 2 or
-    * more channels are updating the same messages in different transactions.
-    */
-   protected void orderReferences(List references)
-   {      
-      Collections.sort(references, MessageOrderComparator.instance);
-   }
-   
-   protected void handleBeforeCommit1PC(List refsToAdd, List refsToRemove, Transaction tx)
-      throws Exception
-   {
-      //TODO - A slight optimisation - it's possible we have refs referring to the same message
-      //       so we will end up acquiring the lock more than once which is unnecessary. If find
-      //       unique set of messages can avoid this.
-
-      List allRefs = new ArrayList(refsToAdd.size() + refsToRemove.size());
-
-      for(Iterator i = refsToAdd.iterator(); i.hasNext(); )
-      {
-         ChannelRefPair pair = (ChannelRefPair)i.next();
-         allRefs.add(pair.ref);
-      }
-
-      for(Iterator i = refsToRemove.iterator(); i.hasNext(); )
-      {
-         ChannelRefPair pair = (ChannelRefPair)i.next();
-         allRefs.add(pair.ref);
-      }
-            
-      orderReferences(allRefs);
-      
-      // For one phase we simply add rows corresponding to the refs and remove rows corresponding to
-      // the deliveries in one jdbc tx. We also need to store or remove messages as necessary,
-      // depending on whether they've already been stored or still referenced by other channels.
-         
-      Connection conn = null;
-      PreparedStatement psReference = null;
-      PreparedStatement psInsertMessage = null;
-      PreparedStatement psIncMessage = null;
-      PreparedStatement psDecMessage = null;
-      PreparedStatement psDeleteMessage = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-      
-      try
-      {
-         conn = ds.getConnection();
-         
-         // Obtain locks on all messages
-         getLocks(allRefs);
-         
-         // First the adds
-
-         boolean messageInsertsInBatch = false;
-         boolean messageUpdatesInBatch = false;
-         boolean batch = usingBatchUpdates && refsToAdd.size() > 0;
-
-         if (batch)
-         {
-            psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
-            psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
-            psIncMessage = conn.prepareStatement(getSQLStatement("INC_CHANNEL_COUNT"));
-         }
-
-         for(Iterator i = refsToAdd.iterator(); i.hasNext(); )
-         {
-            ChannelRefPair pair = (ChannelRefPair)i.next();
-            MessageReference ref = pair.ref;
-                                                
-            if (!batch)
-            {
-               psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
-            }
-            
-            // Now store the reference
-            addReference(pair.channelID, ref, psReference, false);
-              
-            if (batch)
-            {
-               psReference.addBatch();
-            }
-            else
-            {
-               int rows = updateWithRetry(psReference);
-               
-               if (trace) { log.trace("Inserted " + rows + " rows"); }                              
-               
-               psReference.close();
-               psReference = null;
-            }
-            
-            Message m = ref.getMessage();        
-            
-            if (!batch)
-            {
-               psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
-               psIncMessage = conn.prepareStatement(getSQLStatement("INC_CHANNEL_COUNT"));
-            }
-                         
-            boolean added;
-            if (!m.isPersisted())
-            {               
-               // First time so add message
-               storeMessage(m, psInsertMessage);
-               added = true;
-               m.setPersisted(true);
-            }
-            else
-            {               
-               // Update message channel count
-               incrementChannelCount(m, psIncMessage);
-               added = false;
-            }
-            
-            if (batch)
-            {
-               if (added)
-               {
-                  psInsertMessage.addBatch();
-                  if (trace) { log.trace("Message does not already exist so inserting it"); }
-                  messageInsertsInBatch = true;
-               }
-               else
-               { 
-                  if (trace) { log.trace("Message already exists so updating count"); }
-                  psIncMessage.addBatch();
-                  messageUpdatesInBatch = true;
-               }
-            }
-            else
-            {
-               if (added)
-               {
-                  if (trace) { log.trace("Message does not already exist so inserting it"); }
-                  int rows = updateWithRetry(psInsertMessage);
-                  if (trace) { log.trace("Inserted " + rows + " rows"); }
-               }
-               else
-               {
-                  if (trace) { log.trace("Message already exists so updating count"); }
-                  int rows = updateWithRetry(psIncMessage);
-                  if (trace) { log.trace("Updated " + rows + " rows"); }
-               }
-               psInsertMessage.close();
-               psInsertMessage = null;
-               psIncMessage.close();
-               psIncMessage = null;
-            }
-         }         
-         
-         if (batch)
-         {
-            // Process the add batch
-
-            int[] rowsReference = updateWithRetryBatch(psReference);
-            
-            if (trace) { logBatchUpdate(getSQLStatement("INSERT_MESSAGE_REF"), rowsReference, "inserted"); }
-            
-            if (messageInsertsInBatch)
-            {
-               int[] rowsMessage = updateWithRetryBatch(psInsertMessage);
-               if (trace) { logBatchUpdate(getSQLStatement("INSERT_MESSAGE"), rowsMessage, "inserted"); }
-            }
-
-            if (messageUpdatesInBatch)
-            {
-               int[] rowsMessage = updateWithRetryBatch(psIncMessage);
-               if (trace) { logBatchUpdate(getSQLStatement("INC_CHANNEL_COUNT"), rowsMessage, "updated"); }
-            }
-            
-            psReference.close();
-            psReference = null;
-            psInsertMessage.close();
-            psInsertMessage = null;
-            psIncMessage.close();
-            psIncMessage = null;
-         }
-         
-         // Now the removes
-
-         psReference = null;
-         psDeleteMessage = null;
-         batch = usingBatchUpdates && refsToRemove.size() > 0;
-
-         if (batch)
-         {
-            psReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
-            psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
-            psDecMessage = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
-         }
-
-         
-         for(Iterator i = refsToRemove.iterator(); i.hasNext(); )
-         {
-            ChannelRefPair pair = (ChannelRefPair)i.next();
-            
-            if (!batch)
-            {
-               psReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
-            }
-            
-            removeReference(pair.channelID, pair.ref, psReference);
-            
-            if (batch)
-            {
-               psReference.addBatch();
-            }
-            else
-            {
-               int rows = updateWithRetry(psReference);
-               if (trace) { log.trace("Deleted " + rows + " rows"); }
-               psReference.close();
-               psReference = null;
-            }
-            
-            if (!batch)
-            {
-               psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
-               psDecMessage = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
-            }
-            
-            Message m = pair.ref.getMessage();
-                                
-            // Update the channel count
-            
-            decrementChannelCount(m, psDecMessage);
-            
-            // Delete the message (if necessary)
-            
-            removeMessage(m, psDeleteMessage);
-                       
-            if (batch)
-            {
-               psDecMessage.addBatch();
-               psDeleteMessage.addBatch();
-            }
-            else
-            {
-               int rows = updateWithRetry(psDecMessage);
-               if (trace) { log.trace("Updated " + rows + " rows"); }
-               
-               rows = updateWithRetry(psDeleteMessage);
-               if (trace) { log.trace("Deleted " + rows + " rows"); }
-
-               psDeleteMessage.close();
-               psDeleteMessage = null;
-               psDecMessage.close();
-               psDecMessage = null;
-            }            
-         }
-         
-         if (batch)
-         {
-            // Process the remove batch
-
-            int[] rows = updateWithRetryBatch(psReference);
-            
-            if (trace) { logBatchUpdate(getSQLStatement("DELETE_MESSAGE_REF"), rows, "deleted"); }
-            
-            rows = updateWithRetryBatch(psDecMessage);
-            
-            if (trace) { logBatchUpdate(getSQLStatement("DEC_CHANNEL_COUNT"), rows, "updated"); }
-
-            rows = updateWithRetryBatch(psDeleteMessage);
-            
-            if (trace) { logBatchUpdate(getSQLStatement("DELETE_MESSAGE"), rows, "deleted"); }
-
-            psReference.close();
-            psReference = null;
-            psDeleteMessage.close();
-            psDeleteMessage = null;
-            psDecMessage.close();
-            psDecMessage = null;
-         }         
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();                  
-         throw e;
-      }
-      finally
-      {
-      	closeStatement(psReference);
-      	closeStatement(psInsertMessage);
-      	closeStatement(psIncMessage);
-      	closeStatement(psDecMessage);
-      	closeStatement(psDeleteMessage);
-      	closeConnection(conn);        
-         try
-         {
-            wrap.end();                        
-         }
-         finally
-         {  
-            //Release the locks
-            this.releaseLocks(allRefs);
-         }
-      }
-   }
-   
-   protected void handleBeforeCommit2PC(List refsToRemove, Transaction tx)
-      throws Exception
-   {          
-      Connection conn = null;
-      PreparedStatement psUpdateMessage = null;
-      PreparedStatement psDeleteMessage = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-      
-      List refs = new ArrayList(refsToRemove.size());
-      Iterator iter = refsToRemove.iterator();
-      while (iter.hasNext())
-      {
-         ChannelRefPair pair = (ChannelRefPair)iter.next();
-         refs.add(pair.ref);
-      }
-            
-      orderReferences(refs);      
-      
-      try
-      {
-         //get locks on all the refs
-         this.getLocks(refs);
-         
-         conn = ds.getConnection();
-                  
-         //2PC commit
-         
-         //First we commit any refs in state "+" to "C" and delete any
-         //refs in state "-", then we
-         //remove any messages due to refs we just removed
-         //if they're not referenced elsewhere
-         
-         commitPreparedTransaction(tx, conn);
-         
-         boolean batch = usingBatchUpdates && refsToRemove.size() > 0;
-
-         if (batch)
-         {
-            psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
-            psUpdateMessage = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
-         }
-                  
-         iter = refsToRemove.iterator();
-         while (iter.hasNext())
-         {
-            ChannelRefPair pair = (ChannelRefPair) iter.next();
-            
-            MessageReference ref = pair.ref;
-            
-            if (!batch)
-            {
-               psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
-               psUpdateMessage = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
-            }
-            
-            Message m = ref.getMessage();
-                                   
-            //We may need to remove the message itself
-            
-            //Update the channel count
-            
-            decrementChannelCount(m, psUpdateMessage);
-            
-            //Remove the message (if necessary)
-            
-            removeMessage(m, psDeleteMessage);          
-                           
-            if (batch)
-            {
-               psUpdateMessage.addBatch();
-                
-               psDeleteMessage.addBatch(); 
-            }
-            else
-            {
-               int rows = updateWithRetry(psUpdateMessage);
-               
-               if (trace) { log.trace("Updated " + rows + " rows"); }
-               
-               rows = updateWithRetry(psDeleteMessage);
-               
-               if (trace) { log.trace("Deleted " + rows + " rows"); }
-               
-               psDeleteMessage.close();
-               psDeleteMessage = null;
-               psUpdateMessage.close();
-               psUpdateMessage = null;
-            }
-         }         
-         
-         if (batch)
-         {
-            int[] rows = updateWithRetryBatch(psUpdateMessage);
-            
-            if (trace) { logBatchUpdate(getSQLStatement("DEC_CHANNEL_COUNT"), rows, "updated"); }
-            
-            psUpdateMessage.close();
-            psUpdateMessage = null;
-            
-            rows = updateWithRetryBatch(psDeleteMessage);
-            
-            if (trace) { logBatchUpdate(getSQLStatement("DELETE_MESSAGE"), rows, "deleted"); }
-            
-            psDeleteMessage.close();
-            psDeleteMessage = null;                           
-         }         
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeStatement(psDeleteMessage);
-      	closeStatement(psUpdateMessage);
-      	closeConnection(conn);        
-         try
-         {
-            wrap.end();
-         }
-         finally
-         {
-            //release the locks
-            this.releaseLocks(refs);
-         }
-      }
-   }
-   
-   protected void handleBeforePrepare(List refsToAdd, List refsToRemove, Transaction tx) throws Exception
-   {
-      //We only need to lock on the adds
-      List refs = new ArrayList(refsToAdd.size());
-      
-      Iterator iter = refsToAdd.iterator();
-      while (iter.hasNext())
-      {
-         ChannelRefPair pair = (ChannelRefPair)iter.next();
-         
-         refs.add(pair.ref);
-      }
-      
-      orderReferences(refs);
-      
-      //We insert a tx record and
-      //a row for each ref with +
-      //and update the row for each delivery with "-"
-      
-      PreparedStatement psReference = null;
-      PreparedStatement psInsertMessage = null;
-      PreparedStatement psUpdateMessage = null;
-      Connection conn = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-      
-      try
-      {
-         //get the locks
-         getLocks(refs);
-         
-         conn = ds.getConnection();
-         
-         //Insert the tx record
-         if (!refsToAdd.isEmpty() || !refsToRemove.isEmpty())
-         {
-            addTXRecord(conn, tx);
-         }
-         
-         iter = refsToAdd.iterator();
-         
-         boolean batch = usingBatchUpdates && refsToAdd.size() > 1;
-         boolean messageInsertsInBatch = false;
-         boolean messageUpdatesInBatch = false;
-         if (batch)
-         {
-            psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
-            psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
-            psUpdateMessage = conn.prepareStatement(getSQLStatement("INC_CHANNEL_COUNT"));
-         }
-         
-         while (iter.hasNext())
-         {
-            ChannelRefPair pair = (ChannelRefPair) iter.next();
-            
-            if (!batch)
-            {
-               psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
-            }
-            
-            prepareToAddReference(pair.channelID, pair.ref, tx, psReference);
-            
-            if (batch)
-            {
-               psReference.addBatch();
-            }
-            else
-            {
-               int rows = updateWithRetry(psReference);
-               
-               if (trace) { log.trace("Inserted " + rows + " rows"); }
-               
-               psReference.close();
-               psReference = null;
-            }
-            
-            if (!batch)
-            {
-               psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
-               psUpdateMessage = conn.prepareStatement(getSQLStatement("INC_CHANNEL_COUNT"));
-            }
-            
-            Message m = pair.ref.getMessage();
-                   
-            boolean added;         
-            
-            if (!m.isPersisted())
-            {
-               //First time so persist the message
-               storeMessage(m, psInsertMessage);
-               
-               m.setPersisted(true);
-               
-               added = true;
-            }
-            else
-            {
-               //Update message channel count
-               incrementChannelCount(m, psUpdateMessage);
-               
-               added = false;
-            }
-            
-            if (batch)
-            {
-               if (added)
-               {
-                  psInsertMessage.addBatch();
-                  messageInsertsInBatch = true;
-               }
-               else
-               {
-                  psUpdateMessage.addBatch();
-                  messageUpdatesInBatch = true;
-               }
-            }
-            else
-            {
-               if (added)
-               {
-                  int rows = updateWithRetry(psInsertMessage);
-                  
-                  if (trace) { log.trace("Inserted " + rows + " rows"); }
-               }
-               else
-               {
-                  int rows = updateWithRetry(psUpdateMessage);
-                  
-                  if (trace) { log.trace("Updated " + rows + " rows"); }
-               }
-               psInsertMessage.close();
-               psInsertMessage = null;
-               psUpdateMessage.close();
-               psUpdateMessage = null;
-            }
-         }         
-         
-         if (batch)
-         {
-            int[] rowsReference = updateWithRetryBatch(psReference);
-            
-            if (trace) { logBatchUpdate(getSQLStatement("INSERT_MESSAGE_REF"), rowsReference, "inserted"); }
-            
-            if (messageInsertsInBatch)
-            {
-               int[] rowsMessage = updateWithRetryBatch(psInsertMessage);
-               
-               if (trace) { logBatchUpdate(getSQLStatement("INSERT_MESSAGE"), rowsMessage, "inserted"); }
-            }
-            if (messageUpdatesInBatch)
-            {
-               int[] rowsMessage = updateWithRetryBatch(psUpdateMessage);
-               
-               if (trace) { logBatchUpdate(getSQLStatement("INC_CHANNEL_COUNT"), rowsMessage, "updated"); }
-            }
-            
-            psReference.close();
-            psReference = null;
-            psInsertMessage.close();
-            psInsertMessage = null;
-            psUpdateMessage.close();
-            psUpdateMessage = null;
-         }
-         
-         //Now the removes
-         
-         iter = refsToRemove.iterator();
-         
-         batch = usingBatchUpdates && refsToRemove.size() > 1;
-         if (batch)
-         {
-            psReference = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_REF"));
-         }
-
-         while (iter.hasNext())
-         {
-            ChannelRefPair pair = (ChannelRefPair) iter.next();
-            
-            if (!batch)
-            {
-               psReference = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_REF"));
-            }
-            
-            prepareToRemoveReference(pair.channelID, pair.ref, tx, psReference);
-            
-            if (batch)
-            {
-               psReference.addBatch();
-            }
-            else
-            {
-               int rows = updateWithRetry(psReference);
-               
-               if (trace) { log.trace("updated " + rows + " rows"); }
-               
-               psReference.close();
-               psReference = null;
-            }
-         }
-         
-         if (batch)
-         {
-            int[] rows = updateWithRetryBatch(psReference);
-            
-            if (trace) { logBatchUpdate(getSQLStatement("UPDATE_MESSAGE_REF"), rows, "updated"); }
-            
-            psReference.close();
-            psReference = null;
-         }
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeStatement(psReference);
-      	closeStatement(psInsertMessage);
-      	closeStatement(psUpdateMessage);
-      	closeConnection(conn);         
-         try
-         {
-            wrap.end();            
-         }
-         finally
-         {
-            //release the locks
-            
-            this.releaseLocks(refs);
-         }
-      }
-   }
-   
-   protected void handleBeforeRollback(List refsToAdd, Transaction tx) throws Exception
-   {
-      //remove refs marked with +
-      //and update rows marked with - to C
-            
-      PreparedStatement psDeleteMessage = null;
-      PreparedStatement psUpdateMessage = null;
-      Connection conn = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-      
-      List refs = new ArrayList(refsToAdd.size());
-      
-      Iterator iter = refsToAdd.iterator();
-      
-      while (iter.hasNext())
-      {
-         ChannelRefPair pair = (ChannelRefPair)iter.next();
-         refs.add(pair.ref);
-      }
-      
-      orderReferences(refs);
-      
-      try
-      {
-         this.getLocks(refs);
-         
-         conn = ds.getConnection();
-         
-         rollbackPreparedTransaction(tx, conn);
-         
-         iter = refsToAdd.iterator();
-         
-         boolean batch = usingBatchUpdates && refsToAdd.size() > 1;
-
-         if (batch)
-         {
-            psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
-            psUpdateMessage = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
-         }
-                                 
-         while (iter.hasNext())
-         {
-            ChannelRefPair pair = (ChannelRefPair) iter.next();
-            
-            if (!batch)
-            {
-               psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
-               psUpdateMessage = conn.prepareStatement(getSQLStatement("DEC_CHANNEL_COUNT"));
-            }
-            
-            Message m = pair.ref.getMessage();
-                                         
-            //We may need to remove the message for messages added during the prepare stage
-                        
-            //update the channel count
-            
-            decrementChannelCount(m, psUpdateMessage);
-            
-            //remove the message (if necessary)
-            
-            removeMessage(m, psDeleteMessage);
-                                        
-            if (batch)
-            {
-               psUpdateMessage.addBatch();
-               
-               psDeleteMessage.addBatch();
-            }
-            else
-            {
-               int rows = updateWithRetry(psUpdateMessage);
-               
-               if (trace) { log.trace("updated " + rows + " rows"); }
-               
-               rows = updateWithRetry(psDeleteMessage);
-               
-               if (trace) { log.trace("deleted " + rows + " rows"); }
-               
-               psDeleteMessage.close();
-               psDeleteMessage = null;
-               psUpdateMessage.close();
-               psUpdateMessage = null;
-            }            
-         }
-         
-         if (batch)
-         {
-            int[] rows = updateWithRetryBatch(psUpdateMessage);
-            
-            if (trace) { logBatchUpdate(getSQLStatement("DEC_CHANNEL_COUNT"), rows, "updated"); }
-            
-            rows = updateWithRetryBatch(psDeleteMessage);
-            
-            if (trace) { logBatchUpdate(getSQLStatement("DELETE_MESSAGE"), rows, "deleted"); }
-            
-            psDeleteMessage.close();
-            psDeleteMessage = null;
-            
-            psUpdateMessage.close();
-            psUpdateMessage = null;            
-         }
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeStatement(psDeleteMessage);
-      	closeStatement(psUpdateMessage);      	
-      	closeConnection(conn);                
-         try
-         {
-            wrap.end();
-         }
-         finally
-         {
-            //release locks
-            this.releaseLocks(refs);
-         }
-      }      
-   }
-   
-   
-   protected void addTXRecord(Connection conn, Transaction tx) throws Exception
-   {
-      if (trace)
-      {
-         log.trace("Inserting tx record for " + tx);
-      }
-      
-      PreparedStatement ps = null;
-      String statement = "UNDEFINED";
-      int rows = -1;
-      int formatID = -1;
-      try
-      {
-         statement = getSQLStatement("INSERT_TRANSACTION");
-         
-         ps = conn.prepareStatement(statement);
-         
-         ps.setLong(1, tx.getId());
-         
-         Xid xid = tx.getXid();
-         
-         formatID = xid.getFormatId();
-         
-         setVarBinaryColumn(2, ps, xid.getBranchQualifier());
-         
-         ps.setInt(3, formatID);
-         
-         setVarBinaryColumn(4, ps, xid.getGlobalTransactionId());
-         
-         rows = updateWithRetry(ps);
-         
-      }
-      finally
-      {
-         if (trace)
-         {
-            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)"));
-         }
-         closeStatement(ps);      
-      }
-   }
-   
-   protected void removeTXRecord(Connection conn, Transaction tx) throws Exception
-   {
-      PreparedStatement ps = null;
-      try
-      {
-         ps = conn.prepareStatement(getSQLStatement("DELETE_TRANSACTION"));
-         
-         ps.setLong(1, tx.getId());
-         
-         int rows = updateWithRetry(ps);
-         
-         if (trace)
-         {
-            log.trace(JDBCUtil.statementToString(getSQLStatement("DELETE_TRANSACTION"), new Long(tx.getId())) + " removed " + rows + " row(s)");
-         }
-      }
-      finally
-      {
-      	closeStatement(ps);    
-      }
-   }  
-   
-   protected void addReference(long channelID, MessageReference ref,
-                               PreparedStatement ps, boolean paged) throws Exception
-   {
-      if (trace) { log.trace("adding " + ref + " to channel " + channelID); }
-      
-      ps.setLong(1, channelID);
-      ps.setLong(2, ref.getMessage().getMessageID());
-      ps.setNull(3, Types.BIGINT);
-      ps.setString(4, "C");
-      ps.setLong(5, getOrdering());
-      if (paged)
-      {
-         ps.setLong(6, ref.getPagingOrder());
-      }
-      else
-      {
-         ps.setNull(6, Types.BIGINT);
-      }
-      ps.setInt(7, ref.getDeliveryCount());
-      ps.setLong(8, ref.getScheduledDeliveryTime());
-   }
-   
-   protected void removeReference(long channelID, MessageReference ref, PreparedStatement ps)
-      throws Exception
-   {
-      if (trace) { log.trace("removing " + ref + " from channel " + channelID); }
-      
-      ps.setLong(1, ref.getMessage().getMessageID());
-      ps.setLong(2, channelID);      
-   }
-   
-   protected void prepareToAddReference(long channelID, MessageReference ref, Transaction tx, PreparedStatement ps)
-     throws Exception
-   {
-      if (trace) { log.trace("adding " + ref + " to channel " + channelID + (tx == null ? " non-transactionally" : " on transaction: " + tx)); }
-      
-      ps.setLong(1, channelID);
-      ps.setLong(2, ref.getMessage().getMessageID());
-      ps.setLong(3, tx.getId());
-      ps.setString(4, "+");
-      ps.setLong(5, getOrdering());
-      ps.setNull(6, Types.BIGINT);      
-      ps.setInt(7, ref.getDeliveryCount());
-      ps.setLong(8, ref.getScheduledDeliveryTime());
-   }
-   
-   protected void prepareToRemoveReference(long channelID, MessageReference ref, Transaction tx, PreparedStatement ps)
-      throws Exception
-   {
-      if (trace)
-      {
-         log.trace("removing " + ref + " from channel " + channelID
-               + (tx == null ? " non-transactionally" : " on transaction: " + tx));
-      }
-      
-      ps.setLong(1, tx.getId()); 
-      ps.setLong(2, ref.getMessage().getMessageID());
-      ps.setLong(3, channelID);           
-   }
-   
-   protected void commitPreparedTransaction(Transaction tx, Connection conn) throws Exception
-   {
-      PreparedStatement ps = null;
-      
-      if (trace) { log.trace(this + " commitPreparedTransaction, tx= " + tx); }
-        
-      try
-      {
-         ps = conn.prepareStatement(getSQLStatement("COMMIT_MESSAGE_REF1"));
-         
-         ps.setLong(1, tx.getId());        
-         
-         int rows = updateWithRetry(ps);
-         
-         if (trace)
-         {
-            log.trace(JDBCUtil.statementToString(getSQLStatement("COMMIT_MESSAGE_REF1"), new Long(tx.getId())) + " removed " + rows + " row(s)");
-         }
-         
-         ps.close();
-         ps = conn.prepareStatement(getSQLStatement("COMMIT_MESSAGE_REF2"));
-         ps.setLong(1, tx.getId());         
-         
-         rows = updateWithRetry(ps);
-         
-         if (trace)
-         {
-            log.trace(JDBCUtil.statementToString(getSQLStatement("COMMIT_MESSAGE_REF2"), new Long(tx.getId())) + " updated " + rows
-                  + " row(s)");
-         }
-         
-         removeTXRecord(conn, tx);
-      }
-      finally
-      {
-      	closeStatement(ps);
-      }
-   }
-   
-   protected void rollbackPreparedTransaction(Transaction tx, Connection conn) throws Exception
-   {
-      PreparedStatement ps = null;
-      
-      try
-      {
-         ps = conn.prepareStatement(getSQLStatement("ROLLBACK_MESSAGE_REF1"));
-         
-         ps.setLong(1, tx.getId());         
-         
-         int rows = updateWithRetry(ps);
-         
-         if (trace)
-         {
-            log.trace(JDBCUtil.statementToString(getSQLStatement("ROLLBACK_MESSAGE_REF1"), new Long(tx.getId())) + " removed " + rows + " row(s)");
-         }
-         
-         ps.close();
-         
-         ps = conn.prepareStatement(getSQLStatement("ROLLBACK_MESSAGE_REF2"));
-         ps.setLong(1, tx.getId());
-         
-         rows = updateWithRetry(ps);
-         
-         if (trace)
-         {
-            log.trace(JDBCUtil.statementToString(getSQLStatement("ROLLBACK_MESSAGE_REF2"), new Long(tx.getId())) + " updated " + rows
-                  + " row(s)");
-         }
-         
-         removeTXRecord(conn, tx);
-      }
-      finally
-      {
-      	closeStatement(ps);
-      }
-   }
-   
-   protected byte[] mapToBytes(Map map) throws Exception
-   {
-      if (map == null || map.isEmpty())
-      {
-         return null;
-      }
-      
-      final int BUFFER_SIZE = 1024;
-       
-      ByteArrayOutputStream bos = new ByteArrayOutputStream(BUFFER_SIZE);
-      
-      DataOutputStream oos = new DataOutputStream(bos);
-      
-      StreamUtils.writeMap(oos, map, true);
-      
-      oos.close();
-      
-      return bos.toByteArray();
-   }
-   
-   protected HashMap bytesToMap(byte[] bytes) throws Exception
-   {
-      if (bytes == null)
-      {
-         return new HashMap();
-      }
-       
-      ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
-      
-      DataInputStream dais = new DataInputStream(bis);
-      
-      HashMap map = StreamUtils.readMap(dais, true);
-      
-      dais.close();
-            
-      return map;
-   }
-   
-
-   //TODO - combine these
-   protected void incrementChannelCount(Message m, PreparedStatement ps) throws Exception
-   {
-      ps.setLong(1, m.getMessageID());
-   }
-         
-   protected void decrementChannelCount(Message m, PreparedStatement ps) throws Exception
-   {
-      ps.setLong(1, m.getMessageID());
-   }
-   
-   /**
-    * Stores the message in the MESSAGE table.
-    */
-   protected void storeMessage(Message m, PreparedStatement ps) throws Exception
-   {      
-      // physically insert the row in the database
-      // first set the fields from org.jboss.messaging.core.Routable
-      ps.setLong(1, m.getMessageID());
-      ps.setString(2, m.isReliable() ? "Y" : "N");
-      ps.setLong(3, m.getExpiration());
-      ps.setLong(4, m.getTimestamp());
-      ps.setByte(5, m.getPriority());
-      
-      //headers
-      byte[] bytes = mapToBytes(((MessageSupport) m).getHeaders());
-      if (bytes != null)
-      {
-         setBytes(ps, 6, bytes);
-      }
-      else
-      {
-         ps.setNull(6, Types.LONGVARBINARY);
-      }
-      
-      byte[] payload = m.getPayloadAsByteArray();
-      if (payload != null)
-      {
-         setBytes(ps, 7, payload);
-      }
-      else
-      {
-         ps.setNull(7, Types.LONGVARBINARY);
-      }
-      
-      //The number of channels that hold a reference to the message - initially always 1
-      ps.setInt(8, 1);     
-      
-      ps.setByte(9, m.getType());
-   }
-   
-   /**
-    * Removes the message from the MESSAGE table.
-    */
-   protected void removeMessage(Message message, PreparedStatement ps) throws Exception
-   {
-      // physically delete the row in the database
-      ps.setLong(1, message.getMessageID());      
-   }
-   
-   protected void setVarBinaryColumn(int column, PreparedStatement ps, byte[] bytes) throws Exception
-   {
-      if (usingTrailingByte)
-      {
-         // Sybase has the stupid characteristic of truncating all trailing in zeros
-         // in varbinary columns
-         // So we add an extra byte on the end when we store the varbinary data
-         // otherwise we might lose data
-         // http://jira.jboss.org/jira/browse/JBMESSAGING-825
-         
-         byte[] res = new byte[bytes.length + 1];
-         
-         System.arraycopy(bytes, 0, res, 0, bytes.length);
-         
-         res[bytes.length] = 127;
-
-         bytes = res;
-      }
-      
-      ps.setBytes(column, bytes);            
-      
-      if (trace) { log.trace("Setting varbinary column of length: " + bytes.length); }
-   }
-   
-   protected byte[] getVarBinaryColumn(ResultSet rs, int columnIndex) throws Exception
-   {
-      byte[] bytes = rs.getBytes(columnIndex);
-      
-      if (usingTrailingByte)
-      {
-         // Get rid of the trailing byte
-         
-         // http://jira.jboss.org/jira/browse/JBMESSAGING-825
-         
-         byte[] newBytes = new byte[bytes.length - 1];
-         
-         System.arraycopy(bytes, 0, newBytes, 0, bytes.length - 1);
-         
-         bytes = newBytes;
-      }
-      
-      return bytes;
-   }
-     
-   // Used for storing message headers and bodies
-   protected void setBytes(PreparedStatement ps, int columnIndex, byte[] bytes) throws Exception
-   {
-      if (usingBinaryStream)
-      {
-         //Set the bytes using a binary stream - likely to be better for large byte[]
-         
-         InputStream is = null;
-         
-         try
-         {
-            is = new ByteArrayInputStream(bytes);
-            
-            ps.setBinaryStream(columnIndex, is, bytes.length);
-         }
-         finally
-         {
-            if (is != null)
-            {
-               is.close();
-            }
-         }
-      }
-      else
-      {
-         //Set the bytes using setBytes() - likely to be better for smaller byte[]
-         
-         setVarBinaryColumn(columnIndex, ps, bytes);
-      }
-   }
-   
-   protected byte[] getBytes(ResultSet rs, int columnIndex) throws Exception
-   {
-      if (usingBinaryStream)
-      {
-         //Get the bytes using a binary stream - likely to be better for large byte[]
-         
-         InputStream is = null;
-         ByteArrayOutputStream os = null;
-         
-         final int BUFFER_SIZE = 4096;
-         
-         try
-         {
-            InputStream i = rs.getBinaryStream(columnIndex);
-            
-            if (i == null)
-            {
-               return null;
-            }
-            
-            is = new BufferedInputStream(rs.getBinaryStream(columnIndex), BUFFER_SIZE);
-            
-            os = new ByteArrayOutputStream(BUFFER_SIZE);
-            
-            int b;
-            while ((b = is.read()) != -1)
-            {
-               os.write(b);
-            }
-            
-            return os.toByteArray();
-         }
-         finally
-         {
-            if (is != null)
-            {
-               is.close();
-            }
-            if (os != null)
-            {
-               os.close();
-            }
-         }
-      }
-      else
-      {
-         //Get the bytes using getBytes() - better for smaller byte[]
-         return getVarBinaryColumn(rs, columnIndex);
-      }
-   }
-   
-   protected void getLocks(List refs)
-   {
-      Iterator iter = refs.iterator();
-      while (iter.hasNext())
-      {
-         MessageReference ref = (MessageReference)iter.next();
-         Message m = ref.getMessage();
-         LockMap.instance.obtainLock(m);        
-      }
-   }
-   
-   protected void releaseLocks(List refs)
-   {
-      Iterator iter = refs.iterator();
-      while (iter.hasNext())
-      {
-         MessageReference ref = (MessageReference)iter.next();
-         Message m = ref.getMessage();
-         LockMap.instance.releaseLock(m);         
-      }
-   }
-   
-   protected void logBatchUpdate(String name, int[] rows, String action)
-   {
-      int count = 0;
-      for (int i = 0; i < rows.length; i++)
-      {
-         count += rows[i];
-      }
-      log.trace("Batch update " + name + ", " + action + " total of " + count + " rows");
-   }
-   
-   protected int updateWithRetry(PreparedStatement ps) throws Exception
-   {
-      return updateWithRetry(ps, false)[0];
-   }
-   
-   protected int[] updateWithRetryBatch(PreparedStatement ps) throws Exception
-   {
-      return updateWithRetry(ps, true);
-   }
-   
-   //PersistentServiceSupport overrides ----------------------------
-   
-   protected Map getDefaultDDLStatements()
-   {
-      Map map = new LinkedHashMap();
-      //Message reference
-      map.put("CREATE_MESSAGE_REFERENCE",
-              "CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, " +
-              "MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, " +
-              "DELIVERY_COUNT INTEGER, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))");
-      map.put("CREATE_IDX_MESSAGE_REF_TX", "CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)");
-      map.put("CREATE_IDX_MESSAGE_REF_ORD", "CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)");
-      map.put("CREATE_IDX_MESSAGE_REF_PAGE_ORD", "CREATE INDEX JBM_MSG_REF__PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)");
-      map.put("CREATE_IDX_MESSAGE_REF_MESSAGE_ID", "CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)");      
-      map.put("CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY", "CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)");
-      //Message
-      map.put("CREATE_MESSAGE",
-              "CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), " +
-              "EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, HEADERS LONGVARBINARY, " +
-              "PAYLOAD LONGVARBINARY, CHANNEL_COUNT INTEGER, TYPE TINYINT, " +
-              "PRIMARY KEY (MESSAGE_ID))"); 
-      //Transaction
-      map.put("CREATE_TRANSACTION",
-              "CREATE TABLE JBM_TX (" +
-              "TRANSACTION_ID BIGINT, BRANCH_QUAL VARBINARY(254), " +
-              "FORMAT_ID INTEGER, GLOBAL_TXID VARBINARY(254), PRIMARY KEY (TRANSACTION_ID))");
-      //Counter
-      map.put("CREATE_COUNTER",
-              "CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))");
-      return map;
-   }
-      
-   protected Map getDefaultDMLStatements()
-   {                
-      Map map = new LinkedHashMap();
-      //Message reference
-      map.put("INSERT_MESSAGE_REF",
-              "INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) " +
-              "VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
-      map.put("DELETE_MESSAGE_REF", "DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'");
-      map.put("UPDATE_MESSAGE_REF",
-              "UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' " +
-              "WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'");
-      map.put("UPDATE_PAGE_ORDER", "UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?");
-      map.put("COMMIT_MESSAGE_REF1", "UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'");
-      map.put("COMMIT_MESSAGE_REF2", "DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'");
-      map.put("ROLLBACK_MESSAGE_REF1", "DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'");
-      map.put("ROLLBACK_MESSAGE_REF2", "UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'");
-      map.put("LOAD_PAGED_REFS",
-              "SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF " +
-              "WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD");
-      map.put("LOAD_UNPAGED_REFS",
-              "SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' " +
-              "AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD");
-      map.put("LOAD_REFS",
-              "SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' " +
-              "AND CHANNEL_ID = ? ORDER BY ORD");      
-      
-      map.put("UPDATE_REFS_NOT_PAGED", "UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?");       
-      map.put("SELECT_MIN_MAX_PAGE_ORD", "SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?");
-      map.put("SELECT_EXISTS_REF", "SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?");
-      map.put("SELECT_EXISTS_REF_MESSAGE_ID", "SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?");
-      map.put("UPDATE_DELIVERY_COUNT", "UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?");
-      map.put("UPDATE_CHANNEL_ID", "UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?");
-      //Message
-      map.put("LOAD_MESSAGES",
-              "SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, " +
-              "PRIORITY, HEADERS, PAYLOAD, TYPE " +
-              "FROM JBM_MSG");
-      map.put("INSERT_MESSAGE",
-              "INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, " +
-              "TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, CHANNEL_COUNT, TYPE) " +           
-              "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)" );
-      map.put("INC_CHANNEL_COUNT", "UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT + 1 WHERE MESSAGE_ID=?");
-      map.put("DEC_CHANNEL_COUNT", "UPDATE JBM_MSG SET CHANNEL_COUNT = CHANNEL_COUNT - 1 WHERE MESSAGE_ID=?");
-      map.put("DELETE_MESSAGE", "DELETE FROM JBM_MSG WHERE MESSAGE_ID=? AND CHANNEL_COUNT = 0");
-      map.put("MESSAGE_ID_COLUMN", "MESSAGE_ID");
-      map.put("MESSAGE_EXISTS", "SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?");
-      //Transaction
-      map.put("INSERT_TRANSACTION",
-              "INSERT INTO JBM_TX (TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) " +
-              "VALUES(?, ?, ?, ?)");
-      map.put("DELETE_TRANSACTION", "DELETE FROM JBM_TX WHERE TRANSACTION_ID = ?");
-      map.put("SELECT_PREPARED_TRANSACTIONS", "SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX");
-      map.put("SELECT_MESSAGE_ID_FOR_REF", "SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD");
-      map.put("SELECT_MESSAGE_ID_FOR_ACK", "SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD");
-      
-      //Counter
-      map.put("UPDATE_COUNTER", "UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?");
-      map.put("SELECT_COUNTER", "SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=?");
-      map.put("INSERT_COUNTER", "INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)");
-      //Other
-      map.put("SELECT_ALL_CHANNELS", "SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF");      
-      return map;
-   }
-   
-   // Private -------------------------------------------------------
-   
-
-   
-   private int[] updateWithRetry(PreparedStatement ps, boolean batch) throws Exception
-   {
-      final int MAX_TRIES = 25;      
-      
-      int rows = 0;
-      
-      int[] rowsArr = null;
-      
-      int tries = 0;
-      
-      while (true)
-      {
-         try
-         {
-            if (batch)
-            {
-               rowsArr = ps.executeBatch();
-            }
-            else
-            {
-               rows = ps.executeUpdate();
-            }
-            
-            if (tries > 0)
-            {
-               log.warn("Update worked after retry");
-            }
-            break;
-         }
-         catch (SQLException e)
-         {
-            log.warn("SQLException caught - assuming deadlock detected, try:" + (tries + 1), e);
-            tries++;
-            if (tries == MAX_TRIES)
-            {
-               log.error("Retried " + tries + " times, now giving up");
-               throw new IllegalStateException("Failed to update references");
-            }
-            log.warn("Trying again after a pause");
-            //Now we wait for a random amount of time to minimise risk of deadlock
-            Thread.sleep((long)(Math.random() * 500));
-         }  
-      }
-      
-      if (batch)
-      {
-         return rowsArr;
-      }
-      else
-      {
-         return new int[] { rows };
-      }
-   }
-   
-   private List getMessageChannelPair(String sqlQuery, long transactionId) throws Exception
-   {
-      if (trace) log.trace("loading message and channel ids for tx [" + transactionId + "]");
-      
-      Connection conn = null;
-      PreparedStatement ps = null;
-      ResultSet rs = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-      
-      try
-      {
-         conn = ds.getConnection();
-         
-         ps = conn.prepareStatement(sqlQuery);
-         
-         ps.setLong(1, transactionId);
-         
-         rs = ps.executeQuery();
-         
-         //Don't use a Map. A message could be in multiple channels in a tx, so if you use a map
-         //when you put the same message again it's going to overwrite the previous put!!
-         
-         List holders = new ArrayList();
-         
-         //Unique set of messages
-         Set msgIds = new HashSet();
-         
-         //TODO it would probably have been simpler just to have done all this in a SQL JOIN rather
-         //than do the join in memory.....
-         
-         class Holder
-         {
-            long messageId;
-            long channelId;
-            Holder(long messageId, long channelId)
-            {
-               this.messageId = messageId;
-               this.channelId = channelId;
-            }
-         }
-                  
-         while(rs.next())
-         {            
-            long messageId = rs.getLong(1);
-            long channelId = rs.getLong(2);
-            
-            Holder holder = new Holder(messageId, channelId);
-            
-            holders.add(holder);
-                        
-            msgIds.add(new Long(messageId));
-            
-            if (trace) log.trace("Loaded MsgID: " + messageId + " and ChannelID: " + channelId);
-         }
-         
-         Map messageMap = new HashMap();
-         
-         List messages = getMessages(new ArrayList(msgIds));
-         
-         for (Iterator iter = messages.iterator(); iter.hasNext(); )
-         {
-            Message msg = (Message)iter.next();
-            
-            messageMap.put(new Long(msg.getMessageID()), msg);            
-         }
-         
-         List returnList = new ArrayList();
-         
-         for (Iterator iter = holders.iterator(); iter.hasNext(); )
-         {
-            Holder holder = (Holder)iter.next();
-            
-            Message msg = (Message)messageMap.get(new Long(holder.messageId));
-            
-            if (msg == null)
-            {
-               throw new IllegalStateException("Cannot find message " + holder.messageId);
-            }
-            
-            MessageChannelPair pair = new MessageChannelPair(msg, holder.channelId);
-            
-            returnList.add(pair);
-         }
-         
-         return returnList;
-      }
-      catch (Exception e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-      	closeResultSet(rs);
-      	closeStatement(ps);
-      	closeConnection(conn);
-         wrap.end();
-      }
-   }
-   
-   private synchronized long getOrdering()
-   {
-      //We generate the ordering for the message reference by taking the lowest 48 bits of the current time and
-      //concatenating with a 15 bit rotating counter to form a string of 63 bits which we then place
-      //in the right most bits of a long, giving a positive signed 63 bit integer.
-      
-      //Having a time element in the ordering means we don't have to maintain a counter in the database
-      //It also helps with failover since if two queues merge after failover then, the ordering will mean
-      //their orderings interleave nicely and they still get consumed in pretty much time order
-      
-      //We only have to guarantee ordering per session, so having slight differences of time on different nodes is
-      //not a problem
-      
-      //The time element is good for about 8919 years - if you're still running JBoss Messaging then, I suggest you need an
-      //upgrade!
-      
-      long order = System.currentTimeMillis();
-      
-      order = order << 15;
-      
-      order = order | orderCount;
-      
-      if (orderCount == Short.MAX_VALUE)
-      {
-         orderCount = 0;
-      }
-      else
-      {
-         orderCount++;
-      }
-      
-      return order;
-   }
-
-   // Inner classes -------------------------------------------------
-        
-   private static class ChannelRefPair
-   {
-      private long channelID;
-      private MessageReference ref;
-      
-      private ChannelRefPair(long channelID, MessageReference ref)
-      {
-         this.channelID = channelID;
-         this.ref = ref;
-      }
-   }
-   
-   private class TransactionCallback implements TxCallback
-   {
-      private Transaction tx;
-      
-      private List refsToAdd;
-      
-      private List refsToRemove;
-      
-      private TransactionCallback(Transaction tx)
-      {
-         this.tx = tx;
-         
-         refsToAdd = new ArrayList();
-         
-         refsToRemove = new ArrayList();
-      }
-      
-      private void addReferenceToAdd(long channelId, MessageReference ref)
-      {
-         refsToAdd.add(new ChannelRefPair(channelId, ref));
-      }
-      
-      private void addReferenceToRemove(long channelId, MessageReference ref)
-      {
-         refsToRemove.add(new ChannelRefPair(channelId, ref));
-      }
-      
-      public void afterCommit(boolean onePhase)
-      {
-         //NOOP
-      }
-      
-      public void afterPrepare()
-      {
-         //NOOP
-      }
-      
-      public void afterRollback(boolean onePhase)
-      {
-         //NOOP
-      }
-      
-      public void beforeCommit(boolean onePhase) throws Exception
-      {
-         if (onePhase)
-         {
-            handleBeforeCommit1PC(refsToAdd, refsToRemove, tx);
-         }
-         else
-         {
-            handleBeforeCommit2PC(refsToRemove, tx);
-         }
-      }
-      
-      public void beforePrepare() throws Exception
-      {
-         handleBeforePrepare(refsToAdd, refsToRemove, tx);
-      }
-      
-      public void beforeRollback(boolean onePhase) throws Exception
-      {
-         if (onePhase)
-         {
-            //NOOP - nothing in db
-         }
-         else
-         {
-            handleBeforeRollback(refsToAdd, tx);
-         }
-      }
-   }
-   
-   static class MessageOrderComparator implements Comparator
-   {
-      static MessageOrderComparator instance = new MessageOrderComparator();
-      
-      public int compare(Object o1, Object o2)
-      {        
-         MessageReference ref1 = (MessageReference)o1;
-         MessageReference ref2 = (MessageReference)o2;
-
-         long id1 = ref1.getMessage().getMessageID();         
-         long id2 = ref2.getMessage().getMessageID(); 
-         
-         return (id1 < id2 ? -1 : (id1 == id2 ? 0 : 1));
-      }      
-   }
-   
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManagerService.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManagerService.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManagerService.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,162 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin;
-
-import javax.transaction.TransactionManager;
-
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.util.ExceptionUtil;
-
-/**
- * A JDBCPersistenceManagerService
- * 
- * MBean wrapper around a JDBCPersistenceManager
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public class JDBCPersistenceManagerService extends JDBCServiceSupport
-{
-   private PersistenceManager persistenceManager;
-   
-   private boolean started;
-   
-   private boolean usingBatchUpdates;
-   
-   private boolean usingBinaryStream = true;
-   
-   private boolean usingTrailingByte = false;
-   
-   private int maxParams = 100;
-   
-   // Constructors --------------------------------------------------------
-   
-   public JDBCPersistenceManagerService()
-   {      
-   }
-   
-   // ServerPlugin implementation ------------------------------------------
-   
-   public MessagingComponent getInstance()
-   {
-      return persistenceManager;
-   }
-   
-   // ServiceMBeanSupport overrides -----------------------------------------
-   
-   protected synchronized void startService() throws Exception
-   {
-      if (started)
-      {
-         throw new IllegalStateException("Service is already started");
-      }
-      
-      super.startService();
-      
-      try
-      {  
-         TransactionManager tm = getTransactionManagerReference();
-         
-         persistenceManager =
-            new JDBCPersistenceManager(ds, tm, sqlProperties,
-                                       createTablesOnStartup, usingBatchUpdates,
-                                       usingBinaryStream, usingTrailingByte, maxParams);
-         
-         persistenceManager.start();
-         
-         started = true;
-      }
-      catch (Throwable t)
-      {
-         throw ExceptionUtil.handleJMXInvocation(t, this + " startService");
-      } 
-   }
-   
-   protected void stopService() throws Exception
-   {
-      if (!started)
-      {
-         throw new IllegalStateException("Service is not started");
-      }
-      
-      try
-      {
-         persistenceManager.stop();
-         
-         persistenceManager = null;
-         
-         started = false;
-      }
-      catch (Throwable t)
-      {
-         throw ExceptionUtil.handleJMXInvocation(t, this + " startService");
-      } 
-      
-      log.debug(this + " stopped");
-   }
-   
-   // MBean attributes -------------------------------------------------------
-   
-   public boolean isUsingBatchUpdates()
-   {
-      return usingBatchUpdates;
-   }
-   
-   public void setUsingBatchUpdates(boolean b)
-   {
-      usingBatchUpdates = b;
-   }
-   
-   public int getMaxParams()
-   {
-      return maxParams;
-   }
-   
-   public void setMaxParams(int maxParams)
-   {
-      this.maxParams = maxParams;
-   }
-   
-   public boolean isUsingBinaryStream()
-   {
-      return usingBinaryStream;
-   }
-   
-   public void setUsingBinaryStream(boolean b)
-   {
-      usingBinaryStream = b;
-   }
-   
-   public boolean isUsingTrailingByte()
-   {
-      return usingTrailingByte;
-   }
-   
-   public void setUsingTrailingByte(boolean b)
-   {
-      usingTrailingByte = b;
-   }
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/JDBCServiceSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/JDBCServiceSupport.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/JDBCServiceSupport.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,184 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Properties;
-
-import javax.management.MBeanServerInvocationHandler;
-import javax.management.ObjectName;
-import javax.naming.InitialContext;
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
-
-import org.jboss.messaging.core.plugin.contract.ServerPlugin;
-import org.jboss.messaging.util.ExceptionUtil;
-import org.jboss.system.ServiceMBeanSupport;
-import org.jboss.tm.TransactionManagerServiceMBean;
-
-/**
- * MBean wrapper for any service that needs database attributes
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public abstract class JDBCServiceSupport extends ServiceMBeanSupport implements ServerPlugin
-{
-   // Constants ------------------------------------------------------------------------------------
-
-   // Static ---------------------------------------------------------------------------------------
-
-   // Attributes -----------------------------------------------------------------------------------
-
-   protected DataSource ds;
-   protected Properties sqlProperties;
-   protected boolean createTablesOnStartup = true;
-
-   private String dataSourceJNDIName;
-   private ObjectName tmObjectName;
-   private TransactionManager tm;
-
-   // Constructors ---------------------------------------------------------------------------------
-
-   // 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!");
-         }
-
-      }
-      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;
-   }
-
-   // Public ---------------------------------------------------------------------------------------
-
-   // Package protected ----------------------------------------------------------------------------
-
-   // Protected ------------------------------------------------------------------------------------
-
-   protected TransactionManager getTransactionManagerReference()
-   {
-      // lazy initialization
-      if (tm == null)
-      {
-         TransactionManagerServiceMBean tms =
-            (TransactionManagerServiceMBean)MBeanServerInvocationHandler.
-            newProxyInstance(getServer(), tmObjectName, TransactionManagerServiceMBean.class, false);
-
-         tm = tms.getTransactionManager();
-      }
-
-      return tm;
-   }
-
-   // Private --------------------------------------------------------------------------------------
-
-   // Inner classes --------------------------------------------------------------------------------
-
-}
-

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/JDBCSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/JDBCSupport.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/JDBCSupport.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,376 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.sql.DataSource;
-import javax.transaction.Status;
-import javax.transaction.TransactionManager;
-
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
-
-/**
- * Common functionality for messaging components that need to access a database.
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public class JDBCSupport implements MessagingComponent
-{
-   private static final Logger log = Logger.getLogger(JDBCSupport.class);
-   
-   private static boolean trace = log.isTraceEnabled();
-      
-   protected DataSource ds;
-   
-   private TransactionManager tm;
-      
-   protected Properties sqlProperties;
-         
-   private Map defaultDMLStatements;
-   
-   private Map defaultDDLStatements;
-       
-   private boolean createTablesOnStartup = true;
-      
-   public JDBCSupport()
-   {
-      defaultDMLStatements = new LinkedHashMap();
-      
-      defaultDDLStatements = new LinkedHashMap();
-      
-      sqlProperties = new Properties();
-   }
-   
-   public JDBCSupport(DataSource ds, TransactionManager tm, Properties sqlProperties,
-                      boolean createTablesOnStartup)
-   {
-      this();
-      
-      this.ds = ds;
-      
-      this.tm = tm;
-      
-      if (sqlProperties != null)
-      {
-         this.sqlProperties = sqlProperties;
-      }
-      
-      this.createTablesOnStartup = createTablesOnStartup;
-   }
-      
-   // MessagingComponent overrides ---------------------------------
-   
-   public void start() throws Exception
-   {
-      defaultDMLStatements.putAll(getDefaultDMLStatements());
-      
-      defaultDDLStatements.putAll(getDefaultDDLStatements());
-
-      // Make a copy without startup statements
-      Properties sqlPropertiesCopy = new Properties();
-
-      for (Iterator iterSQL = sqlProperties.entrySet().iterator(); iterSQL.hasNext();)
-      {
-         Map.Entry entry = (Map.Entry) iterSQL.next();
-         if (!this.ignoreVerificationOnStartup((String)entry.getKey()))
-         {
-            sqlPropertiesCopy.put(entry.getKey(), entry.getValue());
-         }
-      }
-
-      //Validate the SQL properties
-      Iterator iter = sqlPropertiesCopy.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 (!sqlPropertiesCopy.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 SQL properties");
-            }
-         }
-         
-         iter = defaultDDLStatements.keySet().iterator();
-         
-         while (iter.hasNext())
-         {
-            String statementName = (String)iter.next();
-            
-            if (sqlPropertiesCopy.get(statementName) == null)
-            {
-               throw new IllegalStateException("SQL statement " + statementName + " is not specified in the SQL properties");
-            }
-         }
-      }
-      
-      if (createTablesOnStartup)
-      {
-         createSchema();
-      }
-      
-      log.debug(this + " started");      
-   }
-   public void stop() throws Exception
-   {
-      log.debug(this + " stopped");
-   }
-   
-   // 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);
-      }
-      
-      return sqlProperties.getProperty(statementName, defaultStatement);
-   }
-   
-   protected Map getDefaultDMLStatements()
-   {                
-      return Collections.EMPTY_MAP;
-   }
-   
-   protected Map getDefaultDDLStatements()
-   {
-      return Collections.EMPTY_MAP;
-   }
-
-   /** Subclasses might choose to not cross check the maps on certain statements.
-    *  An example would be POPULATE.TABLES on JDBCJMSUserManagerService */
-   protected boolean ignoreVerificationOnStartup(String statementName)
-   {
-      return false;
-   }
-   
-   protected void closeResultSet(ResultSet rs)
-   {
-   	if (rs != null)
-      {
-         try
-         {
-            rs.close();
-         }
-         catch (Throwable e)
-         {
-         	if (trace)
-         	{
-         		log.trace("Failed to close result set", e);
-         	}
-         }
-      }
-   }
-   
-   protected void closeStatement(Statement st)
-   {
-   	if (st != null)
-      {
-         try
-         {
-         	st.close();
-         }
-         catch (Throwable e)
-         {
-         	if (trace)
-         	{
-         		log.trace("Failed to close statement", e);
-         	}
-         }
-      }
-   }
-   
-   protected void closeConnection(Connection conn)
-   {
-   	if (conn != null)
-      {
-         try
-         {
-         	conn.close();
-         }
-         catch (Throwable e)
-         {
-         	if (trace)
-         	{
-         		log.trace("Failed to close statement", e);
-         	}
-         }
-      }
-   }
-   // Private ----------------------------------------------------------------
-              
-   private void createSchema() throws Exception
-   {      
-      // Postgresql will not process any further commands in a transaction after a create table
-      // fails: org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands
-      // ignored until end of transaction block. Therefore we need to ensure each CREATE is executed
-      // in its own transaction
-                              
-      for(Iterator i = defaultDDLStatements.keySet().iterator(); i.hasNext(); )
-      {
-         Connection conn = null;      
-         
-         Statement st = null;
-                  
-         TransactionWrapper tx = new TransactionWrapper();
-                  
-         try
-         {                        
-            conn = ds.getConnection();
-                        
-            String statementName = (String)i.next();
-             
-            String statement = getSQLStatement(statementName);
-            
-            if (!"IGNORE".equals(statement))
-            {               
-               try
-               {
-                  if (log.isTraceEnabled()) { log.trace("Executing: " + statement); }
-                      
-                  st = conn.createStatement();
-                  
-                  st.executeUpdate(statement);
-               }
-               catch (SQLException e) 
-               {
-                  log.debug("Failed to execute: " + statement, e);
-                  
-                  tx.exceptionOccurred();
-               }  
-            }
-         }
-         finally
-         {
-         	if (st != null)
-            {
-               try
-               {
-                  st.close();
-               }
-               catch (Throwable t)
-               {}
-            }
-            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
-      {
-         oldTx = tm.suspend();
-         
-         tm.begin();
-      }
-      
-      public void end() throws Exception
-      {
-         try
-         {
-            if (Status.STATUS_MARKED_ROLLBACK == tm.getStatus())
-            {
-               failed = true;
-               if (trace) { log.trace("Rolling back tx"); }
-               tm.rollback();               
-            }
-            else
-            {
-               if (trace) { log.trace("Committing tx"); }
-               tm.commit();
-            }
-         }
-         finally
-         {
-            if (oldTx != null && tm != null)
-            {
-               if (trace) { log.trace("Resuming tx"); }
-               tm.resume(oldTx);
-            }
-         }
-      }      
-      
-      public void exceptionOccurred() throws Exception
-      {
-         tm.setRollbackOnly();
-      }
-      
-      public boolean isFailed()
-      {
-         return failed;
-      }
-   }
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/LockMap.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/LockMap.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/LockMap.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,106 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.messaging.core.plugin;
-
-import java.util.Map;
-
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
-import EDU.oswego.cs.dl.util.concurrent.ReentrantLock;
-
-/**
- * 
- * A LockMap.
- * 
- * This class effectively enables arbitrary objects to be locked
- * It does this by maintaining a mutex for each object in a map
- * When no more locks held, object is removed from the map
- * 
- * @author <a href="tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class LockMap
-{ 
-   protected Map map;
-   
-   private static class Entry
-   {
-      ReentrantLock lock = new ReentrantLock();
-      int refCount;   
-   }
-   
-   public static final LockMap instance = new LockMap();
-   
-   private LockMap()
-   {
-      this.map = new ConcurrentHashMap();
-   }
-   
-   public void obtainLock(Object obj)
-   {      
-      Entry entry = null;
-      synchronized (obj)
-      {
-         entry = (Entry)map.get(obj);
-         if (entry == null)
-         {
-            entry = new Entry();
-            map.put(obj, entry);
-         }        
-         entry.refCount++;
-      }
-      try
-      {
-         entry.lock.acquire();
-      }
-      catch (InterruptedException e)
-      {
-         throw new IllegalStateException("Thread interrupted while acquiring lock");
-      }
-   }
-   
-   public void releaseLock(Object obj)
-   {
-      synchronized (obj)
-      {
-         Entry entry = (Entry)map.get(obj);
-         if (entry == null)
-         {
-            throw new IllegalArgumentException("Cannot find mutex in map for " + obj);
-         }    
-         if (entry.refCount == 1)
-         {
-            map.remove(obj);
-         }
-         entry.refCount--;
-         entry.lock.release();         
-      }      
-   }
-   
-   public int getSize()
-   {
-      return map.size();
-   }
-}
-
-

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/contract/ClusteredPostOffice.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/ClusteredPostOffice.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/ClusteredPostOffice.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.messaging.core.plugin.contract;
-
-import java.util.Collection;
-
-import org.jboss.messaging.core.plugin.postoffice.Binding;
-import org.jboss.messaging.core.plugin.postoffice.cluster.LocalClusteredQueue;
-import org.jboss.messaging.core.plugin.postoffice.cluster.Peer;
-
-/**
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public interface ClusteredPostOffice extends PostOffice, Peer
-{
-   public static final String VIEW_CHANGED_NOTIFICATION = "VIEW_CHANGED";
-   public static final String FAILOVER_COMPLETED_NOTIFICATION = "FAILOVER_COMPLETED";
-
-   /**
-    * Bind a queue to the post office under a specific condition such that it is available across
-    * the cluster.
-    *
-    * @param condition - the condition to be used when routing references.
-    */
-   Binding bindClusteredQueue(Condition condition, LocalClusteredQueue queue) throws Exception;
-
-   /**
-    * Unbind a clustered queue from the post office.
-    *
-    * @param queueName - the unique name of the queue.
-    */
-   Binding unbindClusteredQueue(String queueName) throws Throwable;
-
-   Collection listAllBindingsForCondition(Condition condition) throws Exception;   
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/contract/Condition.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/Condition.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/Condition.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,40 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.contract;
-
-import org.jboss.messaging.core.message.MessageReference;
-
-/**
- * A Condition
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public interface Condition
-{
-   boolean matches(Condition routingCondition, MessageReference ref);
-   
-   String toText();
-}

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

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/contract/FailoverMapper.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/FailoverMapper.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/FailoverMapper.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,44 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.contract;
-
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A FailoverMapper
- * 
- * Determines the mapping between a set of nodes and their failover nodes
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public interface FailoverMapper
-{
-   /**
-    * @param nodes Set<Integer>.
-    */
-   Map generateMapping(Set nodes);
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/contract/MessageStore.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/MessageStore.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/MessageStore.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,46 +0,0 @@
-/**
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.messaging.core.plugin.contract;
-
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-
-/**
- * An interface to a referencing/dereferencing message store.
- *
- * @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$</ttH>
- *
- * $Id$
- */
-public interface MessageStore extends MessagingComponent
-{
-   /**
-    * 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
-    *
-    * @param m The Message for which to create the MessageReference
-    * @return The new MessageReference
-    */
-   MessageReference reference(Message m);
-   
-   /**
-    * Return a new reference for a message already stored in the store and identified by <messageID>
-    * @param messageID
-    * @return The reference or null if the message is not already stored in the store
-    */
-   MessageReference reference(long messageID);
-
-   /**
-    * Remove a message from the store
-    * 
-    * @param messageID
-    * @return
-    */
-   public boolean forgetMessage(long messageID);   
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/contract/MessagingComponent.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/MessagingComponent.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/MessagingComponent.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.plugin.contract;
-
-/**
- * A MessagingComponent
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public interface MessagingComponent
-{
-   void start() throws Exception;
-   
-   void stop() throws Exception;
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/contract/MessagingService.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/MessagingService.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/MessagingService.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.plugin.contract;
-
-/**
- * A MessagingService
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public interface MessagingService
-{
-   public void start() throws Exception;
-   
-   public void stop() throws Exception;
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,181 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.messaging.core.plugin.contract;
-
-import java.util.List;
-
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.tx.Transaction;
-
-/**
- * The interface to the persistence manager.
- *
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @author <a href="mailto:Konda.Madhu at uk.mizuho-sc.com">Madhu Konda</a>
- * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
- *
- * @version <tt>1.1</tt>
- *
- * PersistenceManager.java,v 1.1 2006/02/22 17:33:42 timfox Exp
- */
-public interface PersistenceManager extends MessagingComponent
-{
-   void addReference(long channelID, MessageReference ref, Transaction tx) throws Exception;
-
-   void removeReference(long channelID, MessageReference ref, Transaction tx) throws Exception;
-   
-   void updateDeliveryCount(long channelID, MessageReference ref) throws Exception;
-   
-   // XA Recovery functionality
-   
-   List retrievePreparedTransactions() throws Exception;
-   
-   List getMessageChannelPairRefsForTx(long transactionId) throws Exception;
-
-   List getMessageChannelPairAcksForTx(long transactionId) throws Exception;
-
-      
-   // Paging functionality - TODO we should split this out into its own interface
-
-   void pageReferences(long channelID, List references, boolean paged) throws Exception;
-   
-   void removeDepagedReferences(long channelID, List refs) throws Exception;
-    
-   void updatePageOrder(long channelID, List references) throws Exception;
-   
-   void updateReferencesNotPagedInRange(long channelID, long orderStart, long orderEnd, long num)
-      throws Exception;
-   
-   List getPagedReferenceInfos(long channelID, long orderStart, int number) throws Exception;
-   
-   InitialLoadInfo loadFromStart(long channelID, int fullSize) throws Exception;
-   
-   InitialLoadInfo mergeAndLoad(long fromChannelID, long toChannelID, int numberToLoad,
-                                long firstPagingOrder, long nextPagingOrder) 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;
-   
-   // Clustering recovery related functionality
-   
-   boolean referenceExists(long channelID, long messageID) throws Exception;
-
-   // Failover elated functionality (checkDuplicates on send)
-
-   boolean referenceExists(long messageID) throws Exception;
-
-   // Interface value classes ----------------------------------------------------------------------
-
-   class MessageChannelPair
-   {
-      private Message message;
-      
-      private long channelId;
-      
-      public MessageChannelPair(Message message, long channelId)
-      {
-         this.message = message;
-         
-         this.channelId = channelId;
-      }
-      
-      public Message getMessage()
-      {
-         return message;
-      }
-      
-      public long getChannelId()
-      {
-         return channelId;
-      }
-   }
-   
-   class ReferenceInfo
-   {
-      private long messageId;
-      
-      private int deliveryCount;
-      
-      private long scheduledDelivery;
-      
-      public ReferenceInfo(long msgId, int deliveryCount, long scheduledDelivery)
-      {
-         this.messageId = msgId;
-         
-         this.deliveryCount = deliveryCount;
-         
-         this.scheduledDelivery = scheduledDelivery;
-      }    
-      
-      public long getMessageId()
-      {
-         return messageId;
-      }
- 
-      public int getDeliveryCount()
-      {
-         return deliveryCount;
-      }      
-      
-      public long getScheduledDelivery()
-      {
-         return scheduledDelivery;
-      }
-   }
-   
-   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;
-      }
-   }
-   
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/contract/PostOffice.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/PostOffice.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/PostOffice.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.plugin.contract;
-
-import java.util.Collection;
-
-import org.jboss.messaging.core.Queue;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.postoffice.Binding;
-import org.jboss.messaging.core.tx.Transaction;
-
-/**
- * 
- * A PostOffice
- * 
- * A post office holds bindings of queues to conditions. When routing a reference, the post office
- * routes the reference to any binding whose condition matches the condition specified in the call
- * to route(...)
- * 
- * Currently we only support conditions where the condition is an exact text match, and there is a
- * single binding per queue.
- * 
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public interface PostOffice extends MessagingComponent
-{
-   String getOfficeName();
-   
-   Binding bindQueue(Condition condition, Queue queue) throws Exception;
-
-   Binding unbindQueue(String queueName) throws Throwable;
-
-   /**
-    * List the bindings that match the specified condition
-    */
-   Collection getBindingsForCondition(Condition condition) throws Exception;
-
-   
-   /**
-    * Get the binding for the specified queue name.
-    */
-   Binding getBindingForQueueName(String queueName) throws Exception;
-
-   /**
-    * Route a reference.
-    *
-    * @param condition - the message will be routed to a queue if specified condition matches the
-    *        condition of the binding.
-    * @param tx - the transaction or null if not in the context of a transaction.
-    *
-    * @return true if reference was accepted by at least one queue.
-    */
-   boolean route(MessageReference ref, Condition condition, Transaction tx) throws Exception; 
-   
-   /**
-    * 
-    * @return true if it is a non clustered post office
-    */
-   boolean isLocal();
-   
-   Binding getBindingforChannelId(long channelId) throws Exception;
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/contract/ReplicationListener.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/ReplicationListener.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/ReplicationListener.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,43 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.contract;
-
-import java.io.Serializable;
-import java.util.Map;
-
-/**
- * A ReplicationListener
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public interface ReplicationListener
-{
-   /**
-    * @param updatedReplicantMap - the updated replicant map. It contains ALL current replicants for
-    *        the given key.
-    */
-   void onReplicationChange(Serializable key, Map updatedReplicantMap, boolean added, int originatingNodeId);
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/contract/Replicator.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/Replicator.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/Replicator.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,74 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.contract;
-
-import java.io.Serializable;
-import java.util.Map;
-
-/**
- * A Replicator
- * 
- * This is used for replicating arbitrary data across a cluster.
- * 
- * Data is structured as follows:
- * 
- * There is an arbitrary key to identify the data, e.g. the connection factory name
- * Then, for that key, there is an entry for each node id.
- *
- * @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$</tt>
- *
- * $Id$
- *
- */
-public interface Replicator
-{
-   /**
-    * Broadcast data across the cluster, updating replication maps on all nodes, including the local
-    * node.
-    */
-   void put(Serializable key, Serializable data) throws Exception;
-
-   /**
-    * Return a node-mapped replicated data.
-    *
-    * @return a Map<Integer(nodeID)-data>. Returns an empty map if no replicants are found for
-    *         'key', but never null.
-    */
-   Map get(Serializable key) throws Exception;
-
-   /**
-    * Updates the replication maps across the cluster by removing the data corresponding to the give
-    * key. Only the data corresponding to the current node is removed.
-    */
-   boolean remove(Serializable key) throws Exception;
-
-   void registerListener(ReplicationListener listener);
-   
-   void unregisterListener(ReplicationListener listener);
-   
-   /** TODO - this method doesn't belong here... We should have POJOized containers updating dependencies
-    *         between ConnectionFActoryJNDIMapper and DefaultClusteredPostOffice */
-   FailoverMapper getFailoverMapper();
-
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/contract/ServerPlugin.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/ServerPlugin.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/ServerPlugin.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,24 +0,0 @@
-/**
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.messaging.core.plugin.contract;
-
-
-/**
- * @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 ServerPlugin
-{
-   /**
-    * A server plugin will be always accessed via a hard reference, so it is essential that each
-    * implementation exposes this method.
-    */
-   MessagingComponent getInstance();
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/Binding.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/Binding.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/Binding.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,43 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice;
-
-import org.jboss.messaging.core.Queue;
-import org.jboss.messaging.core.plugin.contract.Condition;
-
-/**
- * @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$</tt>
- *
- * $Id$
- *
- */
-public interface Binding
-{
-   int getNodeID();
-   
-   Condition getCondition();
-   
-   Queue getQueue();
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/Bindings.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/Bindings.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/Bindings.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,46 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice;
-
-import java.util.Collection;
-
-/**
- * A Bindings
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public interface Bindings
-{
-   void addBinding(Binding binding);
-   
-   boolean removeBinding(Binding binding);
-   
-   Collection getAllBindings();
-   
-   int getDurableCount();
-   
-   boolean isEmpty();
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultBinding.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultBinding.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultBinding.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,111 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice;
-
-import org.jboss.messaging.core.Queue;
-import org.jboss.messaging.core.plugin.contract.Condition;
-
-/**
- * 
- * A DefaultBinding
- *
- * @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$</tt>
- *
- * $Id$
- *
- */
-public class DefaultBinding implements Binding
-{
-   // Constants ------------------------------------------------------------------------------------
-
-   // Static ---------------------------------------------------------------------------------------
-
-   // Attributes -----------------------------------------------------------------------------------
-
-   private int nodeID;
-
-   private Condition condition;
-
-   private Queue queue;
-
-   // this only works if we keep DefautlBinding immutable
-   private String toString;
-
-   // Constructors ---------------------------------------------------------------------------------
-
-   public DefaultBinding()
-   {
-   }
-
-   public DefaultBinding(int nodeID, Condition condition, Queue queue)
-   {
-      this.nodeID = nodeID;
-      this.condition = condition;
-      this.queue = queue;
-   }
-
-   // Binding implementation -----------------------------------------------------------------------
-
-   public int getNodeID()
-   {
-      return nodeID;
-   }
-
-   public Condition getCondition()
-   {
-      return condition;
-   }
-
-   public Queue getQueue()
-   {
-      return queue;
-   }
-
-   // Public ---------------------------------------------------------------------------------------
-
-   public String toString()
-   {
-      if (toString == null)
-      {
-         StringBuffer sb = new StringBuffer("[");
-
-         sb.append(nodeID).append(',');
-         sb.append(queue);
-         sb.append("]");
-         toString = sb.toString();
-      }
-
-      return toString;
-   }
-
-   // Package protected ----------------------------------------------------------------------------
-
-   // Protected ------------------------------------------------------------------------------------
-
-   // Private --------------------------------------------------------------------------------------
-
-   // Inner classes --------------------------------------------------------------------------------
-
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultBindings.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultBindings.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultBindings.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,120 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 
- * A DefaultBindings
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public class DefaultBindings implements Bindings
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-
-   // Attributes ----------------------------------------------------
-
-   // List<Binding>
-   private List bindings;
-   private int durableCount;
-
-   // Constructors --------------------------------------------------
-
-   public DefaultBindings()
-   {
-      bindings = new ArrayList();
-   }
-
-   // Bindings implementation ---------------------------------------
-
-   public void addBinding(Binding binding)
-   {
-      if (bindings.contains(binding))
-      {
-         throw new IllegalArgumentException("Bindings already contains binding: " + binding);
-      }
-      bindings.add(binding);
-
-      if (binding.getQueue().isRecoverable())
-      {
-         durableCount++;
-      }
-   }
-
-   public boolean removeBinding(Binding binding)
-   {
-      boolean removed = bindings.remove(binding);
-
-      if (removed && binding.getQueue().isRecoverable())
-      {
-         durableCount--;
-      }
-
-      return removed;
-   }
-
-   public Collection getAllBindings()
-   {
-      return bindings;
-   }
-
-   public int getDurableCount()
-   {
-      return durableCount;
-   }
-
-   public boolean isEmpty()
-   {
-      return bindings.isEmpty();
-   }
-
-   // Public --------------------------------------------------------
-
-   public String toString()
-   {
-      StringBuffer sb = new StringBuffer("LocalBindings[");
-      sb.append(bindings);
-      sb.append(']');
-      return sb.toString();
-   }
-
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-
-
-
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultPostOffice.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultPostOffice.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultPostOffice.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,905 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.Types;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
-
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.Filter;
-import org.jboss.messaging.core.FilterFactory;
-import org.jboss.messaging.core.Queue;
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.message.SimpleMessageReference;
-import org.jboss.messaging.core.plugin.JDBCSupport;
-import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
-import org.jboss.messaging.core.plugin.contract.Condition;
-import org.jboss.messaging.core.plugin.contract.ConditionFactory;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.plugin.contract.PostOffice;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.messaging.core.tx.TransactionRepository;
-
-import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
-import EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock;
-
-/**
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public class DefaultPostOffice extends JDBCSupport implements PostOffice
-{
-   // Constants ------------------------------------------------------------------------------------
-
-   private static final Logger log = Logger.getLogger(DefaultPostOffice.class);
-
-   // Static ---------------------------------------------------------------------------------------
-
-   private static boolean trace = log.isTraceEnabled();
-
-   // Attributes -----------------------------------------------------------------------------------
-
-   protected MessageStore ms;
-   protected PersistenceManager pm;
-   protected TransactionRepository tr;
-   protected FilterFactory filterFactory;
-   protected ConditionFactory conditionFactory;
-   protected int currentNodeId;
-
-   // Map <NodeID, Map<queueName, Binding>>
-   protected Map nameMaps;
-
-   // Map <Condition, Bindings>
-   protected Map conditionMap;
-
-   // this lock protects the condition and name maps
-   protected ReadWriteLock lock;
-
-   private String officeName;
-
-   // Constructors ---------------------------------------------------------------------------------
-
-   public DefaultPostOffice()
-   {
-   }
-
-   public DefaultPostOffice(DataSource ds, TransactionManager tm, Properties sqlProperties,
-                         boolean createTablesOnStartup,
-                         int nodeId, String officeName, MessageStore ms,
-                         PersistenceManager pm,
-                         TransactionRepository tr, FilterFactory filterFactory,
-                         ConditionFactory conditionFactory)
-   {
-      super (ds, tm, sqlProperties, createTablesOnStartup);
-
-      lock = new ReentrantWriterPreferenceReadWriteLock();
-
-      nameMaps = new LinkedHashMap();
-
-      conditionMap = new LinkedHashMap();
-
-      this.currentNodeId = nodeId;
-      this.ms = ms;
-      this.pm = pm;
-      this.tr = tr;
-      this.filterFactory = filterFactory;
-      this.conditionFactory = conditionFactory;
-      this.officeName = officeName;
-
-   }
-
-   // MessagingComponent implementation ------------------------------------------------------------
-
-   public void start() throws Exception
-   {
-      if (trace) { log.trace(this + " starting"); }
-
-      super.start();
-
-      loadBindings(false);
-
-      log.debug(this + " started");
-   }
-
-   public void stop() throws Exception
-   {
-      stop(true);
-   }
-
-   public void stop(boolean sendNotification) throws Exception
-   {
-      if (trace) { log.trace(this + " stopping"); }
-
-      super.stop();
-
-      log.debug(this + " stopped");
-   }
-
-   // PostOffice implementation --------------------------------------------------------------------
-
-   public String getOfficeName()
-   {
-      return officeName;
-   }
-
-   public Binding bindQueue(Condition condition, Queue queue) throws Exception
-   {
-      if (trace) { log.trace(this + " binding queue " + queue.getName() + " with condition " + condition); }
-
-      if (queue.getName() == 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(new Integer(currentNodeId));
-
-         Binding binding = null;
-
-         if (nameMap != null)
-         {
-            binding = (Binding)nameMap.get(queue.getName());
-         }
-
-         if (binding != null)
-         {
-            throw new IllegalArgumentException("Binding already exists for name " + queue.getName());
-         }
-
-         binding = new DefaultBinding(currentNodeId, condition, queue);
-
-         addBinding(binding);
-
-         if (queue.isRecoverable())
-         {
-            // Need to write the binding to the database
-            insertBinding(binding);
-         }
-
-         return binding;
-      }
-      finally
-      {
-         lock.writeLock().release();
-      }
-   }
-
-   public Binding unbindQueue( String queueName) throws Throwable
-   {
-      if (trace) { log.trace(this + " unbinding queue " + queueName); }
-
-      if (queueName == null)
-      {
-         throw new IllegalArgumentException("Queue name is null");
-      }
-
-      lock.writeLock().acquire();
-
-      try
-      {
-         Binding binding = removeBinding(currentNodeId,queueName);
-
-         if (binding.getQueue().isRecoverable())
-         {
-            //Need to remove from db too
-
-            deleteBinding(currentNodeId, binding.getQueue().getName());
-         }
-
-         binding.getQueue().removeAllReferences();
-
-         return binding;
-      }
-      finally
-      {
-         lock.writeLock().release();
-      }
-   }
-
-   public Collection getBindingsForCondition(Condition condition) throws Exception
-   {
-      return listBindingsForConditionInternal(condition, true);
-   }
-
-   public Binding getBindingForQueueName(String queueName) throws Exception
-   {
-      if (queueName == null)
-      {
-         throw new IllegalArgumentException("Queue name is null");
-      }
-
-      lock.readLock().acquire();
-
-      try
-      {
-         return internalGetBindingForQueueName(queueName);
-      }
-      finally
-      {
-         lock.readLock().release();
-      }
-   }
-
-   public boolean route(MessageReference ref, Condition condition, Transaction tx) throws Exception
-   {
-      if (trace) { log.trace(this + " routing " + ref + " with condition '" + condition + "' " + (tx == null ? "non-transactionally" : " in " + tx)); }
-
-      if (ref == null)
-      {
-         throw new IllegalArgumentException("Message reference is null");
-      }
-
-      if (condition == null)
-      {
-         throw new IllegalArgumentException("Condition key is null");
-      }
-
-      boolean routed = false;
-
-      lock.readLock().acquire();
-
-      try
-      {
-         Bindings bd = (Bindings)conditionMap.get(condition);
-
-         if (bd != null)
-         {
-            boolean startInternalTx = false;
-
-            if (tx == null && ref.getMessage().isReliable())
-            {
-               if (bd.getDurableCount() > 1)
-               {
-                  // When routing a persistent message without a transaction then we may need to
-                  // start an internal transaction in order to route it. This is so we can guarantee
-                  // the message is delivered to all or none of the subscriptions. We need to do
-                  // this if there is more than one durable subscription.
-                  startInternalTx = true;
-               }
-            }
-
-            if (startInternalTx)
-            {
-               tx = tr.createTransaction();
-            }
-
-            Collection bindings = bd.getAllBindings();
-
-            Iterator iter = bindings.iterator();
-
-            while (iter.hasNext())
-            {
-               Binding binding = (Binding)iter.next();
-
-               //Sanity check
-               if (binding.getNodeID() != this.currentNodeId)
-               {
-                  throw new IllegalStateException("Local post office has foreign bindings!");
-               }
-
-               Queue queue = binding.getQueue();
-
-               Delivery del = queue.handle(null, ref, tx);
-
-               if (del != null && del.isSelectorAccepted())
-               {
-                  routed = true;
-               }
-            }
-
-            if (startInternalTx)
-            {
-               //TODO - do we need to rollback if an exception is thrown??
-               tx.commit();
-            }
-         }
-
-         return routed;
-      }
-      finally
-      {
-         lock.readLock().release();
-      }
-   }
-
-   public boolean isLocal()
-   {
-      return true;
-   }
-
-   public Binding getBindingforChannelId(long channelId) throws Exception
-   {
-      lock.readLock().acquire();
-
-      try
-      {
-         Map nameMap = (Map)nameMaps.get(new Integer(currentNodeId));
-
-         if (nameMap == null)
-         {
-            throw new IllegalStateException("Cannot find name map for current node " + currentNodeId);
-         }
-
-         Binding binding = null;
-
-         for (Iterator iterbindings = nameMap.values().iterator(); iterbindings.hasNext();)
-         {
-            Binding itemBinding = (Binding)iterbindings.next();
-
-            if (itemBinding.getQueue().getChannelID() == channelId)
-            {
-               binding = itemBinding;
-               break;
-            }
-         }
-
-         return binding;
-      }
-      finally
-      {
-         lock.readLock().release();
-      }
-   }
-
-   // Public ---------------------------------------------------------------------------------------
-
-   public String printBindingInformation()
-   {
-       StringWriter buffer = new StringWriter();
-       PrintWriter out = new PrintWriter(buffer);
-
-       out.println("Ocurrencies of nameMaps:");
-       out.println("<table border=1>");
-       for (Iterator mapIterator = nameMaps.entrySet().iterator();mapIterator.hasNext();)
-       {
-           Map.Entry entry = (Map.Entry)mapIterator.next();
-           out.println("<tr><td colspan=3><b>Map on node " + entry.getKey() + "</b></td></tr>");
-           Map valuesOnNode = (Map)entry.getValue();
-
-           out.println("<tr><td>Key</td><td>Value</td><td>Class of Value</td></tr>");
-           for (Iterator valuesIterator=valuesOnNode.entrySet().iterator();valuesIterator.hasNext();)
-           {
-               Map.Entry entry2 = (Map.Entry)valuesIterator.next();
-
-               out.println("<tr>");
-               out.println("<td>" + entry2.getKey() + "</td><td>" + entry2.getValue()+
-                  "</td><td>" + entry2.getValue().getClass().getName() + "</td>");
-               out.println("</tr>");
-
-               if (entry2.getValue() instanceof Binding &&
-                  ((Binding)entry2.getValue()).getQueue() instanceof PagingFilteredQueue)
-               {
-                   PagingFilteredQueue queue =
-                      (PagingFilteredQueue)((Binding)entry2.getValue()).getQueue();
-                   List undelivered = queue.undelivered(null);
-                   if (!undelivered.isEmpty())
-                   {
-                       out.println("<tr><td>List of undelivered messages on Paging</td>");
-
-                       out.println("<td colspan=2><table border=1>");
-                       out.println("<tr><td>Reference#</td><td>Message</td></tr>");
-                       for (Iterator i = undelivered.iterator();i.hasNext();)
-                       {
-                           SimpleMessageReference reference = (SimpleMessageReference)i.next();
-                           out.println("<tr><td>" + reference.getInMemoryChannelCount() +
-                              "</td><td>" + reference.getMessage() +"</td></tr>");
-                       }
-                       out.println("</table></td>");
-                       out.println("</tr>");
-                   }
-               }
-           }
-       }
-
-       out.println("</table>");
-       out.println("<br>Ocurrencies of conditionMap:");
-       out.println("<table border=1>");
-       out.println("<tr><td>EntryName</td><td>Value</td>");
-
-       for (Iterator iterConditions = conditionMap.entrySet().iterator();iterConditions.hasNext();)
-       {
-           Map.Entry entry = (Map.Entry)iterConditions.next();
-           out.println("<tr><td>" + entry.getKey() + "</td><td>" + entry.getValue() + "</td></tr>");
-
-           if (entry.getValue() instanceof Bindings)
-           {
-               out.println("<tr><td>Binding Information:</td><td>");
-               out.println("<table border=1>");
-               out.println("<tr><td>Binding</td><td>Queue</td></tr>");
-               Bindings bindings = (Bindings)entry.getValue();
-               for (Iterator i = bindings.getAllBindings().iterator();i.hasNext();)
-               {
-
-                   Binding binding = (Binding)i.next();
-                   out.println("<tr><td>" + binding + "</td><td>" + binding.getQueue() +
-                      "</td></tr>");
-               }
-               out.println("</table></td></tr>");
-           }
-       }
-       out.println("</table>");
-
-       return buffer.toString();
-   }
-
-   public String toString()
-   {
-      return "DefaultPostOffice[" + Integer.toHexString(hashCode()) + "]";
-   }
-
-   // Package protected ----------------------------------------------------------------------------
-
-   // Protected ------------------------------------------------------------------------------------
-
-   /**
-    * Internal methods (e.g. failOver) will already hold a lock and will need to call
-    * getBindingForQueueNames() without a lock. (Also... I dind't move this method to the protected
-    * section of the code as this is related to getBindingForQueueNames).
-    */
-   protected Binding internalGetBindingForQueueName(String queueName)
-   {
-      Map nameMap = (Map)nameMaps.get(new Integer(currentNodeId));
-
-      Binding binding = null;
-
-      if (nameMap != null)
-      {
-         binding = (Binding)nameMap.get(queueName);
-      }
-
-      return binding;
-   }
-
-   protected Collection listBindingsForConditionInternal(Condition condition, boolean localOnly)
-      throws Exception
-   {
-      if (condition == null)
-      {
-         throw new IllegalArgumentException("Condition is null");
-      }
-
-      lock.readLock().acquire();
-
-      try
-      {
-         //We should only list the bindings for the local node
-
-         Bindings cb = (Bindings)conditionMap.get(condition);
-
-         if (cb == null)
-         {
-            return Collections.EMPTY_LIST;
-         }
-         else
-         {
-            List list = new ArrayList();
-
-            Collection bindings = cb.getAllBindings();
-
-            Iterator iter = bindings.iterator();
-
-            while (iter.hasNext())
-            {
-               Binding binding = (Binding)iter.next();
-
-               if (!localOnly || (binding.getNodeID() == this.currentNodeId))
-               {
-                  list.add(binding);
-               }
-            }
-
-            return list;
-         }
-      }
-      finally
-      {
-         lock.readLock().release();
-      }
-   }
-
-   // FIXME - this is not quite right
-   // We should not load any bindings at startup - since then we do not have to create any queues
-   // internally. Creating queues is problematic since there are params we do not know until
-   // destination deploy time e.g. paging params, maxsize etc. This means we have to load the queues
-   // disabled and then set the params and re-activate them which is not clean.
-   protected void loadBindings(boolean nonClusteredOnly) throws Exception
-   {
-      lock.writeLock().acquire();
-
-      Connection conn = null;
-      PreparedStatement ps  = null;
-      ResultSet rs = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-
-      try
-      {
-         conn = ds.getConnection();
-
-         ps = conn.prepareStatement(getSQLStatement("LOAD_BINDINGS"));
-
-         ps.setString(1, officeName);
-
-         rs = ps.executeQuery();
-
-         while (rs.next())
-         {
-            int nodeID = rs.getInt(1);
-            String queueName = rs.getString(2);
-            String conditionText = rs.getString(3);
-            String selector = rs.getString(4);
-
-            if (rs.wasNull())
-            {
-               selector = null;
-            }
-
-            long channelID = rs.getLong(5);
-                       
-            boolean isClustered = rs.getString(6).equals("Y");
-
-            Condition condition = conditionFactory.createCondition(conditionText);
-            
-            if (nonClusteredOnly && isClustered)
-            {
-               // Don't want to load clustered bindings
-            }
-            else
-            {
-               
-               //Temp hack
-               //For non clustered po don't want to load other nodes bindings!
-               if (!(this instanceof ClusteredPostOffice) && (nodeID != this.currentNodeId))
-               {
-                  //Don't load other nodes binding
-               }
-               else if ((this instanceof ClusteredPostOffice) && (nodeID != this.currentNodeId) &&
-                        !isClustered)
-               {
-                  //We don't load non clustered bindings on other nodes
-               }
-               else
-               {
-                  Binding binding = createBinding(nodeID, condition, queueName, channelID,
-                                                  selector, true, isClustered);
-   
-                  log.debug(this + " loaded from database " + binding);
-   
-                  binding.getQueue().deactivate();
-                  addBinding(binding);
-               }
-            }
-         }
-      }
-      finally
-      {
-         lock.writeLock().release();
-
-         if (rs != null)
-         {
-            rs.close();
-         }
-         if (ps != null)
-         {
-            ps.close();
-         }
-         if (conn != null)
-         {
-            conn.close();
-         }
-         wrap.end();
-      }
-   }
-
-   protected Binding createBinding(int nodeID, Condition condition, String queueName,
-                                   long channelID, String filterString, boolean durable,
-                                   boolean isClustered) throws Exception
-   {
-      Filter filter = filterFactory.createFilter(filterString);
-      return createBinding(nodeID, condition, queueName, channelID,
-                           filter, durable, isClustered);
-   }
-
-   protected Binding createBinding(int nodeID, Condition condition, String queueName,
-                                   long channelID, Filter filter, boolean durable,
-                                   boolean isClustered)
-   {
-      Queue queue;
-
-      if (nodeID == currentNodeId)
-      {         
-         queue =
-            new PagingFilteredQueue(queueName, channelID, ms, pm, true, true, -1, filter);
-      }
-      else
-      {
-         throw new IllegalStateException("This is a non clustered post office - should not " +
-                                         "have bindings from different nodes!");
-      }
-
-      return new DefaultBinding(nodeID, condition, queue);
-   }
-
-   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"));
-
-         String filterString =
-            binding.getQueue().getFilter() == null ?
-               null : binding.getQueue().getFilter().getFilterString();
-
-         ps.setString(1, officeName);
-         ps.setInt(2, currentNodeId);
-         ps.setString(3, binding.getQueue().getName());
-         ps.setString(4, binding.getCondition().toText());
-         if (filterString != null)
-         {
-            ps.setString(5, filterString);
-         }
-         else
-         {
-            ps.setNull(5, Types.VARCHAR);
-         }
-         ps.setLong(6, binding.getQueue().getChannelID());        
-         if (binding.getQueue().isClustered())
-         {
-            ps.setString(7, "Y");
-         }
-         else
-         {
-            ps.setString(7, "N");
-         }
-
-         ps.executeUpdate();
-      }
-      finally
-      {
-      	closeStatement(ps);
-      	closeConnection(conn);
-         wrap.end();
-      }
-   }
-
-   protected boolean deleteBinding(int parameterNodeId, String queueName) throws Exception
-   {
-      if (parameterNodeId<0) parameterNodeId=this.currentNodeId;
-      Connection conn = null;
-      PreparedStatement ps  = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-
-      try
-      {
-         conn = ds.getConnection();
-
-         ps = conn.prepareStatement(getSQLStatement("DELETE_BINDING"));
-
-         ps.setString(1, this.officeName);
-         ps.setInt(2, parameterNodeId);
-         ps.setString(3, queueName);
-
-         int rows = ps.executeUpdate();
-
-         return rows == 1;
-      }
-      finally
-      {
-      	closeStatement(ps);
-      	closeConnection(conn);
-         wrap.end();
-      }
-   }
-
-   protected void addBinding(Binding binding)
-   {
-      addToNameMap(binding);
-      addToConditionMap(binding);
-   }
-
-   protected Binding removeBinding(int nodeId, String queueName)
-   {
-      Binding binding = removeFromNameMap(nodeId, queueName);
-
-      removeFromConditionMap(binding);
-
-      return binding;
-   }
-
-   protected void addToNameMap(Binding binding)
-   {
-      Integer nodeID = new Integer(binding.getNodeID());
-      Map nameMap = (Map)nameMaps.get(nodeID);
-
-      if (nameMap == null)
-      {
-         nameMap = new LinkedHashMap();
-         nameMaps.put(nodeID, nameMap);
-      }
-
-      nameMap.put(binding.getQueue().getName(), binding);
-
-      if (trace) { log.trace(this + " added " + binding + " to name map"); }
-   }
-
-   protected void addToConditionMap(Binding binding)
-   {
-      Condition condition = binding.getCondition();
-
-      Bindings bindings = (Bindings)conditionMap.get(condition);
-
-      if (bindings == null)
-      {
-         bindings = new DefaultBindings();
-         conditionMap.put(condition, bindings);
-      }
-
-      bindings.addBinding(binding);
-
-      if (trace) { log.trace(this + " added " + binding + " to condition map"); }
-   }
-
-   protected Binding removeFromNameMap(int nodeId, String queueName)
-   {
-      if (queueName == null)
-      {
-         throw new IllegalArgumentException("Queue name is null");
-      }
-
-      Map nameMap = (Map)nameMaps.get(new Integer(nodeId));
-
-      if (nameMap == null)
-      {
-         throw new IllegalArgumentException("Cannot find any bindings for node Id: " + nodeId);
-      }
-
-      Binding binding = null;
-
-      if (nameMap != null)
-      {
-         binding = (Binding)nameMap.remove(queueName);
-      }
-
-      if (binding == null)
-      {
-         throw new IllegalArgumentException("Name map does not contain binding for " + queueName);
-      }
-
-      if (nameMap.isEmpty())
-      {
-         nameMaps.remove(new Integer(nodeId));
-      }
-
-      return binding;
-   }
-
-   protected void removeFromConditionMap(Binding binding)
-   {
-      Bindings bindings = (Bindings)conditionMap.get(binding.getCondition());
-
-      if (bindings == null)
-      {
-         throw new IllegalStateException("Cannot find condition bindings for " +
-            binding.getCondition());
-      }
-
-      boolean removed = bindings.removeBinding(binding);
-
-      if (!removed)
-      {
-         throw new IllegalStateException("Cannot find binding in condition binding list");
-      }
-
-      if (bindings.isEmpty())
-      {
-         conditionMap.remove(binding.getCondition());
-      }
-   }
-
-   protected Map getDefaultDMLStatements()
-   {
-      Map map = new LinkedHashMap();
-
-      map.put("INSERT_BINDING",
-              "INSERT INTO JBM_POSTOFFICE (" +
-                 "POSTOFFICE_NAME, " +
-                 "NODE_ID, " +
-                 "QUEUE_NAME, " +
-                 "CONDITION, " +
-                 "SELECTOR, " +
-                 "CHANNEL_ID, " +
-                 "CLUSTERED) " +
-              "VALUES (?, ?, ?, ?, ?, ?, ?)");
-
-      map.put("DELETE_BINDING",
-              "DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?");
-
-      map.put("LOAD_BINDINGS",
-              "SELECT " +
-                 "NODE_ID, " +
-                 "QUEUE_NAME, " +
-                 "CONDITION, " +
-                 "SELECTOR, " +
-                 "CHANNEL_ID, " +
-                 "CLUSTERED " +
-                 "FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME  = ?");
-
-      return map;
-   }
-
-   protected Map getDefaultDDLStatements()
-   {
-      Map map = new LinkedHashMap();
-      map.put("CREATE_POSTOFFICE_TABLE",
-              "CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID INTEGER," +
-              "QUEUE_NAME VARCHAR(1023), CONDITION VARCHAR(1023), " +
-              "SELECTOR VARCHAR(1023), CHANNEL_ID BIGINT, " +
-              "CLUSTERED CHAR(1))");
-      return map;
-   }
-
-   // Private --------------------------------------------------------------------------------------
-
-   // Inner classes --------------------------------------------------------------------------------
-
-   // Private -------------------------------------------------------
-                 
-   // Inner classes ------------------------------------------------- 
-      
-}

Added: trunk/src/main/org/jboss/messaging/util/LockMap.java
===================================================================
--- trunk/src/main/org/jboss/messaging/util/LockMap.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/util/LockMap.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,106 @@
+/*
+  * 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.Map;
+
+import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
+import EDU.oswego.cs.dl.util.concurrent.ReentrantLock;
+
+/**
+ * 
+ * A LockMap.
+ * 
+ * This class effectively enables arbitrary objects to be locked
+ * It does this by maintaining a mutex for each object in a map
+ * When no more locks held, object is removed from the map
+ * 
+ * @author <a href="tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1935 $</tt>
+ *
+ * $Id: LockMap.java 1935 2007-01-09 23:29:20Z clebert.suconic at jboss.com $
+ */
+public class LockMap
+{ 
+   protected Map map;
+   
+   private static class Entry
+   {
+      ReentrantLock lock = new ReentrantLock();
+      int refCount;   
+   }
+   
+   public static final LockMap instance = new LockMap();
+   
+   private LockMap()
+   {
+      this.map = new ConcurrentHashMap();
+   }
+   
+   public void obtainLock(Object obj)
+   {      
+      Entry entry = null;
+      synchronized (obj)
+      {
+         entry = (Entry)map.get(obj);
+         if (entry == null)
+         {
+            entry = new Entry();
+            map.put(obj, entry);
+         }        
+         entry.refCount++;
+      }
+      try
+      {
+         entry.lock.acquire();
+      }
+      catch (InterruptedException e)
+      {
+         throw new IllegalStateException("Thread interrupted while acquiring lock");
+      }
+   }
+   
+   public void releaseLock(Object obj)
+   {
+      synchronized (obj)
+      {
+         Entry entry = (Entry)map.get(obj);
+         if (entry == null)
+         {
+            throw new IllegalArgumentException("Cannot find mutex in map for " + obj);
+         }    
+         if (entry.refCount == 1)
+         {
+            map.remove(obj);
+         }
+         entry.refCount--;
+         entry.lock.release();         
+      }      
+   }
+   
+   public int getSize()
+   {
+      return map.size();
+   }
+}
+
+

Modified: trunk/tests/build.xml
===================================================================
--- trunk/tests/build.xml	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/build.xml	2007-06-25 22:24:41 UTC (rev 2796)
@@ -636,6 +636,8 @@
             <fileset dir="${build.tests.classes}">
                <include name="**/jms/**/${test-mask}.class"/>
                <include name="**/thirdparty/**/${test-mask}.class"/>
+<exclude name="**/jms/bridge/**/*Test.class"/>
+
                <exclude name="**/messaging/graveyard/**/*Test.class"/>
                <exclude name="**/jms/WireFormatTest.class"/>
                <exclude name="**/jms/stress/**"/>

Modified: trunk/tests/src/org/jboss/test/messaging/core/BrokenReceiver.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/BrokenReceiver.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/BrokenReceiver.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -25,12 +25,12 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.DeliveryObserver;
-import org.jboss.messaging.core.Receiver;
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.tx.Transaction;
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.DeliveryObserver;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.Receiver;
+import org.jboss.messaging.core.impl.SimpleDelivery;
+import org.jboss.messaging.core.impl.tx.Transaction;
 
 
 /**

Copied: trunk/tests/src/org/jboss/test/messaging/core/IdManagerTest.java (from rev 2781, trunk/tests/src/org/jboss/test/messaging/core/plugin/IdManagerTest.java)
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/IdManagerTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/IdManagerTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,138 @@
+/*
+  * 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.jms.delegate.IDBlock;
+import org.jboss.messaging.core.contract.PersistenceManager;
+import org.jboss.messaging.core.impl.IDManager;
+import org.jboss.messaging.core.impl.JDBCPersistenceManager;
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.tools.ServerManagement;
+import org.jboss.test.messaging.tools.jmx.ServiceContainer;
+
+/**
+ * 
+ * A IdManagerTest.
+ * 
+ * @author <a href="tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ */
+public class IdManagerTest extends MessagingTestCase
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+
+   protected ServiceContainer sc;
+
+   protected PersistenceManager pm;
+   
+   // Constructors --------------------------------------------------
+
+   public IdManagerTest(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(),
+                  sc.getPersistenceManagerSQLProperties(),
+                  true, true, true, false, 100);     
+      pm.start();
+      
+      pm.start();
+            
+      log.debug("setup done");
+   }
+
+   public void tearDown() throws Exception
+   {      
+      if (!ServerManagement.isRemote())
+      {
+         sc.stop();
+         sc = null;
+      }
+      pm.stop();
+      super.tearDown();
+   }
+   
+   public void test1() throws Exception
+   {
+      IDManager idm = new IDManager("test_counter", 1000, pm);
+      idm.start();
+      
+      int blockSize = 37;
+            
+      long nextLow = Long.MIN_VALUE;
+      
+      for (int i = 0; i < 1000; i++)
+      {
+         IDBlock block = idm.getIDBlock(blockSize);
+                   
+         assertTrue(block.getLow() >= nextLow);
+         
+         assertEquals(blockSize, 1 + block.getHigh() - block.getLow());
+         
+         nextLow = block.getHigh() + 1;         
+      }
+      
+      idm.stop();
+   }
+   
+   public void test2() throws Exception
+   {
+      IDManager idm = new IDManager("test_counter2", 100, pm);
+      idm.start();
+         
+      for (int i = 0; i < 1000; i++)
+      {
+         long id = idm.getID();
+         
+         assertEquals(i, id);
+      }
+      
+      idm.stop();
+   }
+
+   // Package protected ---------------------------------------------
+
+   // Protected -----------------------------------------------------
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+
+}
+

Copied: trunk/tests/src/org/jboss/test/messaging/core/JDBCPersistenceManagerTest.java (from rev 2781, trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java)
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/JDBCPersistenceManagerTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/JDBCPersistenceManagerTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,1591 @@
+/*
+* 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 java.io.Serializable;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
+import javax.transaction.TransactionManager;
+import javax.transaction.xa.Xid;
+
+import org.jboss.messaging.core.contract.Channel;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.PersistenceManager;
+import org.jboss.messaging.core.impl.IDManager;
+import org.jboss.messaging.core.impl.JDBCPersistenceManager;
+import org.jboss.messaging.core.impl.message.SimpleMessageStore;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.core.impl.tx.TransactionRepository;
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.tools.ServerManagement;
+import org.jboss.test.messaging.tools.jmx.ServiceContainer;
+import org.jboss.test.messaging.util.CoreMessageFactory;
+import org.jboss.tm.TransactionManagerService;
+import org.jboss.util.id.GUID;
+
+
+/**
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>1.1</tt>
+ *
+ * JDBCPersistenceManagerTest.java,v 1.1 2006/02/22 17:33:44 timfox Exp
+ */
+public class JDBCPersistenceManagerTest extends MessagingTestCase
+{
+   // Attributes ----------------------------------------------------
+
+   protected ServiceContainer sc;
+   
+   protected JDBCPersistenceManager pm;
+   
+   protected MessageStore ms;
+   
+   
+   // Constructors --------------------------------------------------
+
+   public JDBCPersistenceManagerTest(String name)
+   {
+      super(name);
+   }
+
+   public void setUp() throws Exception
+   {
+      if (ServerManagement.isRemote())
+      {
+         fail("This test is not supposed to run remotely!");
+      }
+
+      super.setUp();
+
+      sc = new ServiceContainer("all");
+      sc.start();                
+      
+   }
+   
+   protected void doSetup(boolean batch, boolean useBinaryStream,
+                          boolean trailingByte, int maxParams) throws Throwable
+   {
+      pm = createPM(batch, useBinaryStream, trailingByte, maxParams);         
+      ms = new SimpleMessageStore();      
+   }
+   
+   protected JDBCPersistenceManager createPM(boolean batch, boolean useBinaryStream,
+                                             boolean trailingByte, int maxParams) throws Throwable
+   {      
+      JDBCPersistenceManager p =
+         new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager(),
+                  sc.getPersistenceManagerSQLProperties(),
+                  true, batch, useBinaryStream, trailingByte, maxParams);
+      p.start();
+      return p;
+   }
+
+   public void tearDown() throws Exception
+   {
+      if (!ServerManagement.isRemote())
+      {
+         sc.stop();
+         sc = null;
+      }
+      pm.stop();
+      ms.stop();
+      super.tearDown();
+   }
+   
+   
+   public void testAddRemoveGetReferences_Batch() throws Throwable
+   {
+      addRemoveGetReferences(true);
+   }
+   
+   public void testAddRemoveGetReferences_NoBatch() throws Throwable
+   {
+      addRemoveGetReferences(false);
+   }
+   
+   
+   
+         
+   public void testAddRemoveReference() throws Throwable
+   {
+      doSetup(false, false, false, 100);
+      
+      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());
+            
+      }
+   }
+   
+   // Trailing zero
+   // -----------------
+   
+   // Binary Stream
+   
+   //non batch
+   
+   public void testCommit_NotXA_Long_NB_BS_TZ() throws Throwable
+   {
+      doTransactionCommit(false, false, true, true);
+   }
+   
+   public void testCommit_XA_Long_NB_BS_TZ() throws Throwable
+   {
+      doTransactionCommit(true, false, true, true);
+   }
+
+   public void testRollback_NotXA_Long_NB_BS_TZ() throws Throwable
+   {
+      doTransactionRollback(false, false, true, true);
+   }
+       
+   public void testRollback_XA_Long_NB_BS_TZ() throws Throwable
+   {
+      doTransactionRollback(true, false, true, true);
+   }
+   
+
+   //batch
+   
+   public void testCommit_NotXA_Long_B_BS_TZ() throws Throwable
+   {
+      doTransactionCommit(false, true, true, true);
+   }
+     
+   public void testCommit_XA_Long_B_BS_TZ() throws Throwable
+   {
+      doTransactionCommit(true, true, true, true);
+   }
+
+   public void testRollback_NotXA_Long_B_BS_TZ() throws Throwable
+   {
+      doTransactionRollback(false, true, true, true);
+   }
+        
+   public void testRollback_XA_Long_B_BS_TZ() throws Throwable
+   {
+      doTransactionRollback(true, true, true, true);
+   }
+   
+   // No binary stream
+   
+   //non batch
+   
+   public void testCommit_NotXA_Long_NB_BNS_TZ() throws Throwable
+   {
+      doTransactionCommit(false, false, false, true);
+   }
+   
+   public void testCommit_XA_Long_NB_NBS_TZ() throws Throwable
+   {
+      doTransactionCommit(true, false, false, true);
+   }
+
+   public void testRollback_NotXA_Long_NB_NBS_TZ() throws Throwable
+   {
+      doTransactionRollback(false, false, false, true);
+   }
+       
+   public void testRollback_XA_Long_NB_NBS_TZ() throws Throwable
+   {
+      doTransactionRollback(true, false, false, true);
+   }
+   
+
+   //batch
+   
+   public void testCommit_NotXA_Long_B_NBS_TZ() throws Throwable
+   {
+      doTransactionCommit(false, true, false, true);
+   }
+     
+   public void testCommit_XA_Long_B_NBS_TZ() throws Throwable
+   {
+      doTransactionCommit(true, true, false, true);
+   }
+
+   public void testRollback_NotXA_Long_B_NBS_TZ() throws Throwable
+   {
+      doTransactionRollback(false, true, false, true);
+   }
+        
+   public void testRollback_XA_Long_B_NBS_TZ() throws Throwable
+   {
+      doTransactionRollback(true, true, false, true);
+   }
+   
+       
+   // Non trailing zero
+   // -----------------
+   
+   // Binary Stream
+   
+   //non batch
+   
+   public void testCommit_NotXA_Long_NB_BS_NTZ() throws Throwable
+   {
+      doTransactionCommit(false, false, true, false);
+   }
+   
+   public void testCommit_XA_Long_NB_BS_NTZ() throws Throwable
+   {
+      doTransactionCommit(true, false, true, false);
+   }
+
+   public void testRollback_NotXA_Long_NB_BS_NTZ() throws Throwable
+   {
+      doTransactionRollback(false, false, true, false);
+   }
+       
+   public void testRollback_XA_Long_NB_BS_NTZ() throws Throwable
+   {
+      doTransactionRollback(true, false, true, false);
+   }
+   
+
+   //batch
+   
+   public void testCommit_NotXA_Long_B_BS_NTZ() throws Throwable
+   {
+      doTransactionCommit(false, true, true, false);
+   }
+     
+   public void testCommit_XA_Long_B_BS_NTZ() throws Throwable
+   {
+      doTransactionCommit(true, true, true, false);
+   }
+
+   public void testRollback_NotXA_Long_B_BS_NTZ() throws Throwable
+   {
+      doTransactionRollback(false, true, true, false);
+   }
+        
+   public void testRollback_XA_Long_B_BS_NTZ() throws Throwable
+   {
+      doTransactionRollback(true, true, true, false);
+   }
+   
+   // No binary stream
+   
+   //non batch
+   
+   public void testCommit_NotXA_Long_NB_BNS_NTZ() throws Throwable
+   {
+      doTransactionCommit(false, false, false, false);
+   }
+   
+   public void testCommit_XA_Long_NB_NBS_NTZ() throws Throwable
+   {
+      doTransactionCommit(true, false, false, false);
+   }
+
+   public void testRollback_NotXA_Long_NB_NBS_NTZ() throws Throwable
+   {
+      doTransactionRollback(false, false, false, false);
+   }
+       
+   public void testRollback_XA_Long_NB_NBS_NTZ() throws Throwable
+   {
+      doTransactionRollback(true, false, false, false);
+   }
+   
+
+   //batch
+   
+   public void testCommit_NotXA_Long_B_NBS_NTZ() throws Throwable
+   {
+      doTransactionCommit(false, true, false, false);
+   }
+     
+   public void testCommit_XA_Long_B_NBS_NTZ() throws Throwable
+   {
+      doTransactionCommit(true, true, false, false);
+   }
+
+   public void testRollback_NotXA_Long_B_NBS_NTZ() throws Throwable
+   {
+      doTransactionRollback(false, true, false, false);
+   }
+        
+   public void testRollback_XA_Long_B_NBS_NTZ() throws Throwable
+   {
+      doTransactionRollback(true, true, false, false);
+   }
+   
+   
+   
+   
+   protected void addRemoveGetReferences(boolean batch) throws Throwable
+   {
+      doSetup(false, false, false, 100);
+      
+      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.pageReferences(channel1.getChannelID(), refs, false);
+      
+      refs = new ArrayList();
+      refs.add(ref11);
+      refs.add(ref12);
+      refs.add(ref13);
+      refs.add(ref14);
+      refs.add(ref15);
+    
+      pm.pageReferences(channel2.getChannelID(), refs, false);
+                  
+      List refIds = getReferenceIds(channel1.getChannelID());
+      assertNotNull(refIds);
+      assertEquals(10, refIds.size());
+      assertTrue(refIds.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref2.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref3.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref4.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref5.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref6.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref7.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref8.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref9.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref10.getMessage().getMessageID())));
+      
+      refIds = getReferenceIds(channel2.getChannelID());
+      assertNotNull(refIds);
+      assertEquals(5, refIds.size());
+      assertTrue(refIds.contains(new Long(ref11.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref12.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref13.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref14.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref15.getMessage().getMessageID())));
+     
+      
+      List msgs = getMessageIds();
+      assertNotNull(msgs);
+      assertEquals(10, msgs.size());
+      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref3.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref4.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref5.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref6.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref7.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref8.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref9.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref10.getMessage().getMessageID())));
+      
+      List msgIds = new ArrayList();
+      msgIds.add(new Long(ref3.getMessage().getMessageID()));
+      msgIds.add(new Long(ref4.getMessage().getMessageID()));
+      msgIds.add(new Long(ref7.getMessage().getMessageID()));
+      msgIds.add(new Long(ref9.getMessage().getMessageID()));
+      msgIds.add(new Long(ref1.getMessage().getMessageID()));
+      
+      List ms = pm.getMessages(msgIds);
+      assertNotNull(ms);
+      assertEquals(5, ms.size());
+      assertTrue(containsMessage(ms, ref3.getMessage().getMessageID()));
+      assertTrue(containsMessage(ms, ref4.getMessage().getMessageID()));
+      assertTrue(containsMessage(ms, ref7.getMessage().getMessageID()));
+      assertTrue(containsMessage(ms, ref9.getMessage().getMessageID()));
+      assertTrue(containsMessage(ms, ref1.getMessage().getMessageID()));
+      
+      refs = new ArrayList();
+      refs.add(ref12);
+      refs.add(ref13);
+      refs.add(ref14);
+      refs.add(ref15);
+      pm.removeDepagedReferences(channel2.getChannelID(), refs);
+      
+      refIds = getReferenceIds(channel2.getChannelID());
+      assertNotNull(refIds);
+      assertEquals(1, refIds.size());
+      assertTrue(refIds.contains(new Long(ref11.getMessage().getMessageID())));
+      
+      ms = getMessageIds();
+
+      assertNotNull(ms);
+      assertEquals(10, ms.size());
+      
+      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref3.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref4.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref5.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref6.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref7.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref8.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref9.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref10.getMessage().getMessageID())));
+     
+      
+      refs = new ArrayList();
+      refs.add(ref1);
+      refs.add(ref2);
+      refs.add(ref3);
+      pm.removeDepagedReferences(channel1.getChannelID(), refs);
+      
+      refIds = getReferenceIds(channel1.getChannelID());
+      assertNotNull(refIds);
+      assertEquals(7, refIds.size());
+      assertTrue(refIds.contains(new Long(ref4.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref5.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref6.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref7.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref8.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref9.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref10.getMessage().getMessageID())));
+     
+      
+      ms = getMessageIds();
+        
+      assertNotNull(ms);
+      assertEquals(8, ms.size());
+      
+      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref4.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref5.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref6.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref7.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref8.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref9.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref10.getMessage().getMessageID())));
+      
+      refs = new ArrayList();
+      refs.add(ref11);
+      pm.removeDepagedReferences(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.removeDepagedReferences(channel1.getChannelID(), refs);
+      
+      ms = getMessageIds();
+      assertNotNull(ms);
+      assertEquals(0, ms.size());
+   }
+   
+   public void testPageOrders() throws Throwable
+   {
+      doSetup(false, false, false, 100);
+      
+      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.pageReferences(channel.getChannelID(), refs, false); 
+      
+      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);
+      
+      pm.updatePageOrder(channel.getChannelID(), refs);
+      
+      List refInfos = pm.getPagedReferenceInfos(channel.getChannelID(), 0, 10);
+      
+      assertNotNull(refInfos);
+      
+      assertEquals(10, refInfos.size());
+      
+      assertEquals(ref1.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
+      assertEquals(ref2.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
+      assertEquals(ref3.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
+      assertEquals(ref4.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
+      assertEquals(ref5.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());
+      assertEquals(ref6.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(5)).getMessageId());
+      assertEquals(ref7.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(6)).getMessageId());
+      assertEquals(ref8.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(7)).getMessageId());
+      assertEquals(ref9.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(8)).getMessageId());
+      assertEquals(ref10.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(9)).getMessageId());
+      
+      refInfos = pm.getPagedReferenceInfos(channel.getChannelID(), 3, 5);
+      
+      assertNotNull(refInfos);
+      
+      assertEquals(5, refInfos.size());
+      
+      assertEquals(ref4.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
+      assertEquals(ref5.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
+      assertEquals(ref6.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
+      assertEquals(ref7.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
+      assertEquals(ref8.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());
+    
+      pm.updateReferencesNotPagedInRange(channel.getChannelID(), 0, 3, 4);
+      
+      refInfos = pm.getPagedReferenceInfos(channel.getChannelID(), 5, 5);
+      
+      assertNotNull(refInfos);
+      
+      assertEquals(5, refInfos.size());
+          
+      assertEquals(ref6.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
+      assertEquals(ref7.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
+      assertEquals(ref8.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
+      assertEquals(ref9.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
+      assertEquals(ref10.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());                
+   }
+     
+   public void testGetMessages() throws Throwable
+   {
+      doSetup(false, false, false, 100);
+      
+      Channel channel = new SimpleChannel(0, 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]);
+      
+      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);
+      
+      List refIds = getReferenceIds(channel.getChannelID());
+      assertNotNull(refIds);
+      assertEquals(10, refIds.size());
+      assertTrue(refIds.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref2.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref3.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref4.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref5.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref6.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref7.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref8.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref9.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref10.getMessage().getMessageID())));
+      
+      List msgs = getMessageIds();
+      assertNotNull(msgs);
+      assertEquals(10, msgs.size());
+      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref3.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref4.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref5.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref6.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref7.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref8.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref9.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref10.getMessage().getMessageID())));
+      
+      List msgIds = new ArrayList();
+      msgIds.add(new Long(ref3.getMessage().getMessageID()));
+      msgIds.add(new Long(ref4.getMessage().getMessageID()));
+      msgIds.add(new Long(ref7.getMessage().getMessageID()));
+      msgIds.add(new Long(ref9.getMessage().getMessageID()));
+      msgIds.add(new Long(ref1.getMessage().getMessageID()));
+      
+      List ms = pm.getMessages(msgIds);
+      assertNotNull(ms);
+      assertEquals(5, ms.size());
+        
+      assertTrue(containsMessage(ms, ref3.getMessage().getMessageID()));
+      assertTrue(containsMessage(ms, ref4.getMessage().getMessageID()));
+      assertTrue(containsMessage(ms, ref7.getMessage().getMessageID()));
+      assertTrue(containsMessage(ms, ref9.getMessage().getMessageID()));
+      assertTrue(containsMessage(ms, ref1.getMessage().getMessageID()));
+        
+   }
+   
+   public void testGetInitialRefInfos() throws Throwable
+   {
+      doSetup(false, false, false, 100);
+      
+      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.pageReferences(channel.getChannelID(), refs, false); 
+      
+      //First load exactly 10
+      PersistenceManager.InitialLoadInfo info = pm.loadFromStart(channel.getChannelID(), 10);
+      
+      assertNull(info.getMinPageOrdering());
+      assertNull(info.getMaxPageOrdering());
+      
+      List refInfos = info.getRefInfos();
+      
+      assertNotNull(refInfos);
+      assertEquals(10, refInfos.size());
+      
+      assertEquals(ref1.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
+      assertEquals(ref2.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
+      assertEquals(ref3.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
+      assertEquals(ref4.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
+      assertEquals(ref5.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());
+      assertEquals(ref6.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(5)).getMessageId());
+      assertEquals(ref7.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(6)).getMessageId());
+      assertEquals(ref8.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(7)).getMessageId());
+      assertEquals(ref9.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(8)).getMessageId());
+      assertEquals(ref10.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(9)).getMessageId());          
+   }
+      
+   
+   protected boolean containsMessage(List msgs, long msgId)
+   {
+      Iterator iter = msgs.iterator();
+      while (iter.hasNext())
+      {
+         Message m = (Message)iter.next();
+         if (m.getMessageID() == msgId)
+         {
+            return true;
+         }           
+      }
+      return false;
+   }
+   
+   public void testGetMessagesMaxParams() throws Throwable
+   {
+      doSetup(false, false, false, 5);
+      
+      Channel channel = new SimpleChannel(0, 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]);
+      
+      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);
+      
+      List refIds = getReferenceIds(channel.getChannelID());
+      assertNotNull(refIds);
+      assertEquals(10, refIds.size());
+      assertTrue(refIds.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref2.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref3.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref4.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref5.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref6.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref7.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref8.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref9.getMessage().getMessageID())));
+      assertTrue(refIds.contains(new Long(ref10.getMessage().getMessageID())));
+      
+      List msgs = getMessageIds();
+      assertNotNull(msgs);
+      assertEquals(10, msgs.size());
+      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref3.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref4.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref5.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref6.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref7.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref8.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref9.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref10.getMessage().getMessageID())));
+      
+      List msgIds = new ArrayList();
+      msgIds.add(new Long(ref3.getMessage().getMessageID()));
+      msgIds.add(new Long(ref4.getMessage().getMessageID()));
+      msgIds.add(new Long(ref7.getMessage().getMessageID()));
+      msgIds.add(new Long(ref9.getMessage().getMessageID()));
+      msgIds.add(new Long(ref1.getMessage().getMessageID()));
+      
+      List ms = pm.getMessages(msgIds);
+      assertNotNull(ms);
+      assertEquals(5, ms.size());
+      assertTrue(containsMessage(ms, ref3.getMessage().getMessageID()));
+      assertTrue(containsMessage(ms, ref4.getMessage().getMessageID()));
+      assertTrue(containsMessage(ms, ref7.getMessage().getMessageID()));
+      assertTrue(containsMessage(ms, ref9.getMessage().getMessageID()));
+      assertTrue(containsMessage(ms, ref1.getMessage().getMessageID()));   
+   }
+   
+   
+   //Commented out until recovery work is complete
+
+//   public void testRetrievePreparedTransactions() throws Throwable
+//   {
+//      doSetup(false, 100);
+//      
+//      Channel channel = new SimpleChannel(0, ms);
+//      
+//      TransactionRepository txRep = new TransactionRepository(pm, new IDManager("TRANSACTION_ID", 10, pm));
+//      txRep.start();
+//
+//      Message[] messages = createMessages(10);
+//      
+//      Xid[] xids = new Xid[messages.length];
+//      Transaction[] txs = new Transaction[messages.length];
+//      
+//      for (int i = 0; i < messages.length; i++)
+//      {         
+//         xids[i] = new MockXid();
+//         txs[i] = txRep.createTransaction(xids[i]);
+//         MessageReference ref = ms.reference(messages[i]);
+//         pm.addReference(channel.getChannelID(), ref, txs[i]);
+//         txs[i].prepare();
+//      }
+//      
+//      List txList = pm.retrievePreparedTransactions();
+//      assertNotNull(txList);
+//      assertEquals(messages.length, txList.size());
+//      
+//      for (int i = 0; i < xids.length; i++)
+//      {
+//         Xid xid = xids[i];
+//         assertTrue(txList.contains(xid));
+//      }
+//      
+//      //rollback the txs
+//      for (int i = 0; i < txs.length; i++)
+//      {
+//         txs[i].rollback();
+//      }   
+//   }
+   
+   protected Message createMessage(byte i, boolean reliable) throws Throwable
+   {
+      Map headers = generateFilledMap(true);
+
+      return CoreMessageFactory.
+         createCoreMessage(i,
+                           reliable,
+                           System.currentTimeMillis() + 1000 * 60 * 60,
+                           System.currentTimeMillis(),
+                           (byte)(i % 10),
+                           headers,
+                           i % 2 == 0 ? new WibblishObject() : null);
+   }
+   
+   protected Message[] createMessages(int num) throws Throwable
+   {
+      //Generate some messages with a good range of attribute values
+      Message[] messages = new Message[num];
+      for (int i = 0; i < num; i++)
+      {            
+         messages[i] = createMessage((byte)i, true);
+      }
+      return messages;
+   }
+   
+   protected void checkEquivalent(Message m1, Message m2) throws Throwable
+   {
+      if (m1 == m2)
+      {
+         fail();
+      }
+      
+      if (m1 == null || m2 == null)
+      {
+         fail();
+      }
+      
+      //Attributes from org.jboss.messaging.core.Message
+      assertEquals(m1.getMessageID(), m2.getMessageID());
+      assertEquals(m1.isReliable(), m2.isReliable());
+      assertEquals(m1.getExpiration(), m2.getExpiration());
+      assertEquals(m1.isExpired(), m2.isExpired());
+      assertEquals(m1.getTimestamp(), m2.getTimestamp());
+      assertEquals(m1.getPriority(), m2.getPriority());
+      Map m1Headers = m1.getHeaders();
+      Map m2Headers = m2.getHeaders();
+      checkMapsEquivalent(m1Headers, m2Headers);
+      checkMapsEquivalent(m2Headers, m1Headers);
+      
+      if (m1.getPayload() instanceof byte[] && m2.getPayload() instanceof byte[])
+      {
+         this.checkByteArraysEqual((byte[])m1.getPayload(), (byte[])m2.getPayload());
+      }
+      else if (m1.getPayload() instanceof Map && m2.getPayload() instanceof Map)
+      {
+         this.checkMapsEquivalent((Map)m1.getPayload(), (Map)m2.getPayload());
+      }
+      else if (m1.getPayload() instanceof List && m2.getPayload() instanceof List)
+      {
+         this.checkListsEquivalent((List)m1.getPayload(), (List)m2.getPayload());
+      }
+      else
+      {      
+         assertEquals(m1.getPayload(), m2.getPayload());
+      }
+      
+   }
+   
+   protected void checkMapsEquivalent(Map headers1, Map headers2)
+   {
+      Iterator iter = headers1.entrySet().iterator();
+      while (iter.hasNext())
+      {
+         Map.Entry entry1 = (Map.Entry)iter.next();
+         Object value2 = headers2.get(entry1.getKey());
+         assertNotNull(value2);
+         if (value2 instanceof byte[])
+         {
+            checkByteArraysEqual((byte[])entry1.getValue(), (byte[])value2);
+         }
+         else
+         {
+            assertEquals(entry1.getValue(), value2);
+         }
+      }
+   }
+   
+   protected void checkListsEquivalent(List l1, List l2)
+   {      
+      Iterator iter1 = l1.iterator();
+      Iterator iter2 = l2.iterator();
+      while (iter1.hasNext())
+      {
+         Object o1 = iter1.next();
+         Object o2 = iter2.next();
+         
+         if (o1 instanceof byte[])
+         {
+            checkByteArraysEqual((byte[])o1, (byte[])o2);
+         }
+         else
+         {
+            assertEquals(o1, o2);
+         }
+      }
+   }
+   
+   public static class WibblishObject implements Serializable
+   {
+      private static final long serialVersionUID = -822739710811857027L;
+      public String wibble;
+      public WibblishObject()
+      {
+         this.wibble = new GUID().toString();
+      }
+      public boolean equals(Object other)
+      {
+         if (!(other instanceof WibblishObject))
+         {
+            return false;
+         }
+         WibblishObject oo = (WibblishObject)other;
+         return oo.wibble.equals(this.wibble);
+      }
+   }
+   
+   protected HashMap generateFilledMap(boolean useObject)
+   {
+      HashMap headers = new HashMap();
+      for (int j = 0; j < 27; j++)
+      {
+         //put some crap in the map
+         int k;
+         if (useObject)
+         {
+            k = j % 11;
+         }
+         else
+         {
+            k = j % 10;
+         }
+         
+         switch (k)
+         {
+            case 0:
+               headers.put(new GUID().toString(), randString(1000));
+            case 1:
+               headers.put(new GUID().toString(), randByte());
+            case 2:
+               headers.put(new GUID().toString(), randShort());
+            case 3:
+               headers.put(new GUID().toString(), randInt());
+            case 4:
+               headers.put(new GUID().toString(), randLong());
+            case 5:
+               headers.put(new GUID().toString(), randBool());
+            case 6:
+               headers.put(new GUID().toString(), randFloat());
+            case 7:
+               headers.put(new GUID().toString(), randDouble());
+            case 8:
+               headers.put(new GUID().toString(), randLong());
+            case 9:
+               headers.put(new GUID().toString(), randByteArray(500));
+            case 10:
+               headers.put(new GUID().toString(), new WibblishObject());               
+         }
+      }
+      return headers;
+   }
+   
+   protected Byte randByte()
+   {
+      return new Byte((byte)(Math.random() * (2^8 - 1) - (2^7)));
+   }
+   
+   protected Short randShort()
+   {
+      return new Short((short)(Math.random() * (2^16 - 1) - (2^15)));
+   }
+   
+   protected Integer randInt()
+   {
+      return new Integer((int)(Math.random() * (2^32 - 1) - (2^31)));
+   }
+   
+   protected Long randLong()
+   {
+      return new Long((long)(Math.random() * (2^64 - 1) - (2^64)));
+   }
+   
+   protected Boolean randBool()
+   {
+      return new Boolean(Math.random() > 0.5);
+   }
+   
+   protected Float randFloat()
+   {
+      return new Float((float)(Math.random() * 1000000));
+   }
+   
+   protected Double randDouble()
+   {
+      return new Double(Math.random() * 1000000);
+   }
+   
+   protected String randString(int length)
+   {
+      StringBuffer buf = new StringBuffer(length);
+      for (int i = 0; i < length; i++)
+      {
+         buf.append(randChar().charValue());
+      }
+      return buf.toString();
+   }
+   
+   protected byte[] randByteArray(int size)
+   {
+      String s = randString(size / 2);
+      return s.getBytes();
+   }
+   
+   protected Character randChar()
+   {
+      return new Character((char)randShort().shortValue());
+   }
+   
+   protected void checkByteArraysEqual(byte[] b1, byte[] b2)
+   {
+      if (b1 == null || b2 == null)
+      {
+         fail();
+      }
+      if (b1.length != b2.length)
+      {
+         fail();
+      }
+      
+      for (int i = 0; i < b1.length; i++)
+      {
+         assertEquals(b1[i], b2[i]);
+      }
+      
+   }
+   
+   protected class MockXid implements Xid
+   {
+      byte[] branchQual;
+      int formatID;
+      byte[] globalTxId;
+      
+      protected MockXid()
+      {
+         branchQual = new GUID().toString().getBytes();
+         formatID = randInt().intValue();
+         globalTxId = new GUID().toString().getBytes();
+      }
+
+      public byte[] getBranchQualifier()
+      {
+         return branchQual;
+      }
+
+      public int getFormatId()
+      {
+         return formatID;
+      }
+
+      public byte[] getGlobalTransactionId()
+      {
+         return globalTxId;
+      }
+      
+      public boolean equals(Object other)
+      {
+         if (!(other instanceof Xid))
+         {
+            return false;
+         }
+         Xid xother = (Xid)other;
+         if (xother.getFormatId() != this.formatID)
+         {
+            return false;
+         }
+         if (xother.getBranchQualifier().length != this.branchQual.length)
+         {
+            return false;
+         }
+         if (xother.getGlobalTransactionId().length != this.globalTxId.length)
+         {
+            return false;
+         }
+         for (int i = 0; i < this.branchQual.length; i++)
+         {
+            byte[] otherBQ = xother.getBranchQualifier();
+            if (this.branchQual[i] != otherBQ[i])
+            {
+               return false;
+            }
+         }
+         for (int i = 0; i < this.globalTxId.length; i++)
+         {
+            byte[] otherGtx = xother.getGlobalTransactionId();
+            if (this.globalTxId[i] != otherGtx[i])
+            {
+               return false;
+            }
+         }
+         return true;
+      }
+      
+   }
+   
+   protected void doTransactionCommit(boolean xa, boolean batch, boolean useBinaryStream, boolean trailingByte) throws Throwable
+   {
+      doSetup(batch, useBinaryStream, trailingByte, 100);
+
+      Channel channel = new SimpleChannel(0, ms);
+      
+      IDManager idm = new IDManager("TRANSACTION_ID", 10, pm);
+      idm.start();
+      
+      TransactionRepository txRep = new TransactionRepository(pm, ms, idm);
+      txRep.start();
+
+      log.debug("transaction log started");
+
+      Message[] messages = createMessages(10);
+      
+      Message m1 = messages[0];
+      Message m2 = messages[1];
+      Message m3 = messages[2];      
+      Message m4 = messages[3];
+      Message m5 = messages[4];
+
+      Transaction tx = null;
+      if (xa)
+      {         
+         tx = txRep.createTransaction(new MockXid());
+      }
+      else
+      {
+         tx = txRep.createTransaction();
+      }
+      
+      if (xa)
+      {
+    	  assertEquals(1,txRep.getNumberOfRegisteredTransactions());
+      }
+      else
+      {
+    	  assertEquals(0,txRep.getNumberOfRegisteredTransactions());
+      }
+      
+      MessageReference ref1 = ms.reference(m1);
+      MessageReference ref2 = ms.reference(m2);  
+      MessageReference ref3 = ms.reference(m3);       
+      MessageReference ref4 = ms.reference(m4);
+      MessageReference ref5 = ms.reference(m5);
+
+      log.debug("adding references non-transactionally");
+
+      // Add first two refs non transactionally
+      pm.addReference(channel.getChannelID(), ref1, null);
+      pm.addReference(channel.getChannelID(), ref2, null);
+      
+      //check they're there
+      List refs = getReferenceIds(channel.getChannelID());
+      assertNotNull(refs);
+      assertEquals(2, refs.size());
+      assertTrue(refs.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(refs.contains(new Long(ref2.getMessage().getMessageID())));
+      
+      List msgs = getMessageIds();
+      assertNotNull(msgs);
+      assertEquals(2, msgs.size());
+      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));
+
+      log.debug("ref1 and ref2 are there");
+
+      //Add the next 3 refs transactionally
+      pm.addReference(channel.getChannelID(), ref3, tx);
+      pm.addReference(channel.getChannelID(), ref4, tx);
+      pm.addReference(channel.getChannelID(), ref5, tx);
+      
+      //Remove the other 2 transactionally
+      pm.removeReference(channel.getChannelID(), ref1, tx);
+      pm.removeReference(channel.getChannelID(), ref2, tx);
+      
+      //Check the changes aren't visible
+      refs = getReferenceIds(channel.getChannelID());
+      assertNotNull(refs);
+      assertEquals(2, refs.size());
+      assertTrue(refs.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(refs.contains(new Long(ref2.getMessage().getMessageID())));  
+      
+      msgs = getMessageIds();
+      assertNotNull(msgs);
+      assertEquals(2, msgs.size());
+      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));
+      
+      //commit transaction
+      tx.commit();
+
+      assertEquals("numberOfRegisteredTransactions",0,txRep.getNumberOfRegisteredTransactions());
+      
+      //check we can see only the last 3 refs
+      refs = getReferenceIds(channel.getChannelID());
+      assertNotNull(refs);
+      assertEquals(3, refs.size()); 
+      assertTrue(refs.contains(new Long(ref3.getMessage().getMessageID())));
+      assertTrue(refs.contains(new Long(ref4.getMessage().getMessageID())));  
+      assertTrue(refs.contains(new Long(ref5.getMessage().getMessageID())));
+      
+      msgs = getMessageIds();
+      assertNotNull(msgs);
+      assertEquals(3, msgs.size());
+      assertTrue(msgs.contains(new Long(ref3.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref4.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref5.getMessage().getMessageID())));
+   }
+         
+   protected void doTransactionRollback(boolean xa, boolean batch, boolean useBinaryStream, boolean trailingByte) throws Throwable
+   {
+      doSetup(batch, useBinaryStream, trailingByte, 100);
+
+      Channel channel = new SimpleChannel(0, ms);
+      
+      IDManager idm = new IDManager("TRANSACTION_ID", 10, pm);
+      idm.start();
+      
+      TransactionRepository txRep = new TransactionRepository(pm, ms, idm);
+      txRep.start();
+ 
+      Message[] messages = createMessages(10);     
+      
+      Message m1 = messages[0];
+      Message m2 = messages[1];
+      Message m3 = messages[2];      
+      Message m4 = messages[3];
+      Message m5 = messages[4];
+
+      
+      Transaction tx = null;
+      if (xa)
+      {
+         tx = txRep.createTransaction(new MockXid());
+      }
+      else
+      {
+         tx = txRep.createTransaction();
+      }
+      
+      MessageReference ref1 = ms.reference(m1);
+      MessageReference ref2 = ms.reference(m2);  
+      MessageReference ref3 = ms.reference(m3);       
+      MessageReference ref4 = ms.reference(m4);
+      MessageReference ref5 = ms.reference(m5);  
+
+      //Add first two refs non transactionally
+      pm.addReference(channel.getChannelID(), ref1, null);
+      pm.addReference(channel.getChannelID(), ref2, null);
+      
+      //check they're there
+      List refs = getReferenceIds(channel.getChannelID());
+      assertNotNull(refs);
+      assertEquals(2, refs.size());
+      assertTrue(refs.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(refs.contains(new Long(ref2.getMessage().getMessageID())));      
+      
+      List msgs = getMessageIds();
+      assertNotNull(msgs);
+      assertEquals(2, msgs.size());
+      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));
+      
+      
+      
+      //Add the next 3 refs transactionally
+      pm.addReference(channel.getChannelID(), ref3, tx);
+      pm.addReference(channel.getChannelID(), ref4, tx);
+      pm.addReference(channel.getChannelID(), ref5, tx);
+      
+      //Remove the other 2 transactionally
+      pm.removeReference(channel.getChannelID(), ref1, tx);
+      pm.removeReference(channel.getChannelID(), ref2, tx);
+      
+      //Check the changes aren't visible
+      refs = getReferenceIds(channel.getChannelID());
+      assertNotNull(refs);
+      assertEquals(2, refs.size());
+      assertTrue(refs.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(refs.contains(new Long(ref2.getMessage().getMessageID())));  
+      
+      msgs = getMessageIds();
+      assertNotNull(msgs);
+      assertEquals(2, msgs.size());
+      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));
+      
+      //rollback transaction
+      tx.rollback();
+      
+      refs = getReferenceIds(channel.getChannelID());
+      assertNotNull(refs);
+      assertEquals(2, refs.size());
+      assertTrue(refs.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(refs.contains(new Long(ref2.getMessage().getMessageID())));  
+      
+      msgs = getMessageIds();
+      assertNotNull(msgs);
+      assertEquals(2, msgs.size());
+      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
+      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));          
+   }
+   
+   
+   protected List getReferenceIds(long channelId) throws Throwable
+   {
+      InitialContext ctx = new InitialContext();
+
+      TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
+      DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
+      
+      javax.transaction.Transaction txOld = mgr.suspend();
+      mgr.begin();
+
+      Connection conn = ds.getConnection();
+      String sql = "SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE CHANNEL_ID=? ORDER BY ORD";
+      PreparedStatement ps = conn.prepareStatement(sql);
+      ps.setLong(1, channelId);
+   
+      ResultSet rs = ps.executeQuery();
+      
+      List msgIds = new ArrayList();
+      
+      while (rs.next())
+      {
+         long msgId = rs.getLong(1);
+         msgIds.add(new Long(msgId));
+      }
+      rs.close();
+      ps.close();
+      conn.close();
+
+      mgr.commit();
+
+      if (txOld != null)
+      {
+         mgr.resume(txOld);
+      }
+      
+      return msgIds;
+   }
+   
+   protected List getMessageIds() throws Throwable
+   {
+      InitialContext ctx = new InitialContext();
+
+      TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
+      DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
+      
+      javax.transaction.Transaction txOld = mgr.suspend();
+      mgr.begin();
+
+      Connection conn = ds.getConnection();
+      String sql = "SELECT MESSAGE_ID FROM JBM_MSG ORDER BY MESSAGE_ID";
+      PreparedStatement ps = conn.prepareStatement(sql);
+      
+      ResultSet rs = ps.executeQuery();
+      
+      List msgIds = new ArrayList();
+      
+      while (rs.next())
+      {
+         long msgId = rs.getLong(1);
+         msgIds.add(new Long(msgId));
+      }
+      rs.close();
+      ps.close();
+      conn.close();
+
+      mgr.commit();
+
+      if (txOld != null)
+      {
+         mgr.resume(txOld);
+      }
+      
+      return msgIds;
+   }
+   
+}
+
+
+

Copied: trunk/tests/src/org/jboss/test/messaging/core/JDBCUtilTest.java (from rev 2781, trunk/tests/src/org/jboss/test/messaging/core/persistence/JDBCUtilTest.java)
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/JDBCUtilTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/JDBCUtilTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,84 @@
+/*
+* 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;
+import org.jboss.messaging.util.JDBCUtil;
+
+
+/**
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class JDBCUtilTest extends MessagingTestCase
+{
+   // Attributes ----------------------------------------------------
+
+   // Constructors --------------------------------------------------
+
+   public JDBCUtilTest(String name)
+   {
+      super(name);
+   }
+
+   public void testStatementToStringOneArgument()
+   {
+      String sql = "INSERT INTO A (B) values(?)";
+      String statement = JDBCUtil.statementToString(sql, "X");
+      assertEquals("INSERT INTO A (B) values(X)", statement);
+   }
+
+   public void testStatementToStringTwoArguments()
+   {
+      String sql = "INSERT INTO A (B, C) values(?, ?)";
+      String statement = JDBCUtil.statementToString(sql, "X", "Y");
+      assertEquals("INSERT INTO A (B, C) values(X, Y)", statement);
+   }
+
+   public void testStatementToStringWitNull()
+   {
+      String sql = "INSERT INTO A (B, C) values(?, ?)";
+      String statement = JDBCUtil.statementToString(sql, null, "Y");
+      assertEquals("INSERT INTO A (B, C) values(null, Y)", statement);
+   }
+
+
+   public void testExtraArguments()
+   {
+      String sql = "INSERT INTO A (B, C) values(?, ?)";
+      String statement = JDBCUtil.statementToString(sql, "X", "Y", "Z");
+      assertEquals("INSERT INTO A (B, C) values(X, Y)", statement);
+   }
+
+   public void testNotEnoughArguments()
+   {
+      String sql = "INSERT INTO A (B, C, D) values(?, ?, ?)";
+      String statement = JDBCUtil.statementToString(sql, "X", "Y");
+      assertEquals("INSERT INTO A (B, C, D) values(X, Y, ?)", statement);
+   }
+
+
+
+
+}
+
+

Copied: trunk/tests/src/org/jboss/test/messaging/core/MessageStoreTestBase.java (from rev 2781, trunk/tests/src/org/jboss/test/messaging/core/plugin/base/MessageStoreTestBase.java)
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/MessageStoreTestBase.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/MessageStoreTestBase.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,349 @@
+/*
+* 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 java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.tools.jmx.ServiceContainer;
+import org.jboss.test.messaging.util.CoreMessageFactory;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.MessageStore;
+
+
+/**
+ * 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.
+ *
+ * @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 MessageStoreTestBase extends MessagingTestCase
+{
+   // Constants -----------------------------------------------------
+
+   public static final int NUMBER_OF_MESSAGES = 100;
+
+   // Static --------------------------------------------------------       
+
+   /**
+    * Makes sure the given reference refers the given message.
+    */
+   public static void assertCorrectReference(MessageReference ref, Message m)
+   {
+      assertEquals(m.getMessageID(), ref.getMessage().getMessageID());
+      assertEquals(m.isReliable(), ref.getMessage().isReliable());
+      assertEquals(m.getExpiration(), ref.getMessage().getExpiration());
+      assertEquals(m.getTimestamp(), ref.getMessage().getTimestamp());
+      assertEquals(m.getPriority(), ref.getMessage().getPriority());
+      assertEquals(0, ref.getDeliveryCount());
+
+      Map messageHeaders = m.getHeaders();
+      Map refHeaders = ref.getMessage().getHeaders();
+      assertEquals(messageHeaders.size(), refHeaders.size());
+
+      for(Iterator i = messageHeaders.keySet().iterator(); i.hasNext(); )
+      {
+         Object header = i.next();
+         Object value = messageHeaders.get(header);
+         assertTrue(refHeaders.containsKey(header));
+         assertEquals(value, refHeaders.get(header));
+      }
+   }
+
+   // Attributes ----------------------------------------------------
+
+   protected ServiceContainer sc;
+   protected MessageStore ms;
+
+   protected Map headers;
+
+   // Constructors --------------------------------------------------
+
+   public MessageStoreTestBase(String name)
+   {
+      super(name);
+   }
+
+   // Public --------------------------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();
+
+      sc = new ServiceContainer("all,-remoting,-security");
+      sc.start();
+
+      headers = new HashMap();
+      headers.put("someKey", "someValue");
+   }
+
+   public void tearDown() throws Exception
+   {
+      headers.clear();
+      headers = null;
+      sc.stop();
+      sc = null;
+
+      super.tearDown();
+   }
+
+   ////
+   //// Non-reliable message
+   ////
+
+   //////
+   ////// One message
+   //////
+
+   ////////
+   //////// One strong reference
+   ////////
+
+   public void testMessageStore_1() throws Exception
+   {
+      Message m = CoreMessageFactory.
+      createCoreMessage(0, false, 777l, 888l, (byte)9, headers, "payload");
+
+      // recoverable store, non-reliable message, one message
+      MessageReference ref = ms.reference(m);
+      assertCorrectReference(ref, m);
+      ref.releaseMemoryReference();
+
+      ref = ms.reference(m.getMessageID());
+      assertNull(ref);
+   }
+
+   ////////
+   //////// Two strong references
+   ////////
+
+   public void testMessageStore_1_1() throws Exception
+   {
+
+      Message m = CoreMessageFactory.
+      createCoreMessage(0, false, 777l, 888l, (byte)9, headers, "payload");
+
+      // recoverable store, non-reliable message, one message
+      MessageReference ref = ms.reference(m);
+      assertCorrectReference(ref, m);
+
+      MessageReference ref2 = ms.reference(m);
+
+      assertCorrectReference(ref2, m);
+   }
+
+   //////
+   ////// Multiple messages
+   //////
+
+   public void testMessageStore_2() throws Exception
+   {
+      Message[] m = new Message[NUMBER_OF_MESSAGES];
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++ )
+      {
+         m[i] = CoreMessageFactory.createCoreMessage(i, false, 700 + i, 800 + i,
+                                             (byte)(i % 10), headers, "payload" + i);
+
+         // recoverable store, non-reliable message, one message
+         refs[i] = ms.reference(m[i]);
+         assertCorrectReference(refs[i], m[i]);
+      }
+
+      // get reachable reference
+
+      for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {         
+         assertCorrectReference(refs[i], m[i]);
+         refs[i].releaseMemoryReference();
+      }
+
+      for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         assertNull(ms.reference(m[i].getMessageID()));
+      }
+   }
+
+   ////
+   //// Reliable message
+   ////
+
+   //////
+   ////// One message
+   //////
+
+   ////////
+   //////// One strong reference
+   ////////
+
+   public void testMessageStore_3() throws Exception
+   {
+      Message m = CoreMessageFactory.
+      createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");
+
+      // recoverable store, non-reliable message, one message
+      MessageReference ref = ms.reference(m);
+      assertCorrectReference(ref, m);
+
+      ref.releaseMemoryReference();
+
+      // there's no strong reference to the unique message reference anymore, so the message store
+      // should be cleaned of everything that pertains to that message
+
+      ref = ms.reference(m.getMessageID());
+      assertNull(ref);
+   }
+
+   ////////
+   //////// Two strong references
+   ////////
+
+   public void testMessageStore_3_1() throws Exception
+   {
+      Message m = CoreMessageFactory.
+      createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");
+
+      // recoverable store, non-reliable message, one message
+      MessageReference ref = ms.reference(m);
+      assertCorrectReference(ref, m);
+
+      MessageReference ref2 = ms.reference(m);
+
+      assertCorrectReference(ref2, m);
+   }
+
+   //////
+   ////// Multiple messages
+   //////
+
+   public void testMessageStore_4() throws Exception
+   {
+      Message[] m = new Message[NUMBER_OF_MESSAGES];
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++ )
+      {
+         m[i] = CoreMessageFactory.createCoreMessage(i, true, 700 + i, 800 + i,
+                                             (byte)(i % 10), headers, "payload" + i);
+
+         // recoverable store, non-reliable message, one message
+         refs[i] = ms.reference(m[i]);
+         assertCorrectReference(refs[i], m[i]);
+      }
+
+      // get reachable reference
+
+      for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {         
+         refs[i].releaseMemoryReference();
+      }
+
+      // there are no strong references to the message reference anymore, so the message store
+      // should be cleaned of everything that pertains to those message
+
+      for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         assertNull(ms.reference(m[i].getMessageID()));
+      }
+   }
+   
+   public void testMessageStore_6() throws Exception
+   {
+
+      Message m = CoreMessageFactory.
+      createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");
+
+      // non-recoverable store, non-reliable message, one message
+      MessageReference ref = ms.reference(m);
+      assertCorrectReference(ref, m);
+      
+      //Create another reference from that reference
+      MessageReference ref2 = ms.reference(m);
+          
+      ref.releaseMemoryReference();
+      
+      MessageReference ref3 = ms.reference(m.getMessageID());
+      assertNotNull(ref3);
+      ref3.releaseMemoryReference();
+      
+      assertCorrectReference(ref3, m);
+      
+      ref2.releaseMemoryReference();
+
+      // there's no strong reference to the unique message reference anymore, so the message store
+      // should be cleaned of everything that pertains to that message
+
+      ref3 = ms.reference(m.getMessageID());
+      assertNull(ref3);
+   }
+   
+   public void testMessageStore_7() throws Exception
+   {
+      Message m = CoreMessageFactory.
+      createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");
+
+      // non-recoverable store, non-reliable message, one message
+      MessageReference ref = ms.reference(m);
+      assertCorrectReference(ref, m);
+      
+      MessageReference ref2 = ms.reference(ref.getMessage().getMessageID());
+      assertNotNull(ref2);      
+      assertCorrectReference(ref2, m);
+      
+      MessageReference ref3 = ms.reference(ref.getMessage().getMessageID());
+      assertNotNull(ref3);      
+      assertCorrectReference(ref3, m);
+      
+      ref.releaseMemoryReference();
+      ref2.releaseMemoryReference();
+      ref3.releaseMemoryReference();
+      
+      MessageReference ref4 = ms.reference(ref.getMessage().getMessageID());
+            
+      assertNull(ref4);                
+   }
+
+   // Package protected ---------------------------------------------
+
+   // Protected -----------------------------------------------------
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+
+}

Added: trunk/tests/src/org/jboss/test/messaging/core/MessagingQueueTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/MessagingQueueTestBase.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/MessagingQueueTestBase.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,5458 @@
+/*
+* 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 java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.Filter;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.PersistenceManager;
+import org.jboss.messaging.core.contract.Receiver;
+import org.jboss.messaging.core.impl.IDManager;
+import org.jboss.messaging.core.impl.JDBCPersistenceManager;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.core.impl.message.CoreMessage;
+import org.jboss.messaging.core.impl.message.SimpleMessageStore;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.core.impl.tx.TransactionRepository;
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.tools.jmx.ServiceContainer;
+import org.jboss.test.messaging.util.CoreMessageFactory;
+
+/**
+ * The QueueTest test strategy is to try as many combination as it makes sense of the following
+ * variables:
+ *
+ * 1. The Queue can be non-recoverable  or
+ *    recoverable.
+ * 2. The Queue 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 MessagingQueueTestBase 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 MessagingQueue queue;
+   
+   protected IDManager idm;
+   
+   // Constructors --------------------------------------------------
+
+   public MessagingQueueTestBase(String name)
+   {
+      super(name);
+   }
+
+   // Public --------------------------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();
+      
+      sc = new ServiceContainer("all,-remoting,-security");
+      sc.start();
+
+      pm = new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager(),
+                                      sc.getPersistenceManagerSQLProperties(),
+                                      true, true, true, false, 100);
+      pm.start();
+      
+      idm = new IDManager("TRANSACTION_ID", 10, pm);
+      idm.start();
+      
+      ms = new SimpleMessageStore();
+      ms.start();
+      
+      tr = new TransactionRepository(pm, ms, idm);
+      tr.start();
+      
+   }
+
+   public void tearDown() throws Exception
+   {
+      sc.stop();
+      
+      pm.stop();
+      idm.stop();
+      tr.stop();
+      ms.stop();
+      
+      sc = null;   
+      pm = null;
+      idm = null;
+      ms = null;
+      tr = null;
+      super.tearDown();
+   }
+
+   public static void assertEqualSets(MessageReference[] a, List msgs)
+   {
+      assertEquals(a.length, msgs.size());
+      List l = new ArrayList(msgs);
+
+      for(int i = 0; i < a.length; i++)
+      {
+         for(Iterator j = l.iterator(); j.hasNext(); )
+         {
+            Object o = j.next();
+            Message m = (Message)o;
+            
+            if (a[i].getMessage().getMessageID() == m.getMessageID() &&
+                m.getPayload().equals(a[i].getMessage().getPayload()))
+            {
+               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().getMessage().getMessageID() == ref.getMessage().getMessageID())
+            {
+               j.remove();
+               break;
+            }
+         }
+      }
+
+      if (!l.isEmpty())
+      {
+         fail("Deliveries " + l + " do not match!");
+      }
+   }
+
+
+   // Channel tests -------------------------------------------------
+   
+
+   public void testWithFilter()
+   {
+      Filter f = new SimpleFilter(3);
+                        
+      MessagingQueue queue = new MessagingQueue(1, "queue1", 1, ms, pm, false, -1, f, false, false);
+      queue.activate();
+      
+      Message m1 = new CoreMessage(1, false, 0, 0, (byte)0, null, null);
+      Message m2 = new CoreMessage(2, false, 0, 0, (byte)0, null, null);
+      Message m3 = new CoreMessage(3, false, 0, 0, (byte)0, null, null);
+      Message m4 = new CoreMessage(4, false, 0, 0, (byte)0, null, null);
+      Message m5 = new CoreMessage(5, false, 0, 0, (byte)0, null, null);
+      
+      MessageReference ref1 = ms.reference(m1);
+      MessageReference ref2 = ms.reference(m2);
+      MessageReference ref3 = ms.reference(m3);
+      MessageReference ref4 = ms.reference(m4);
+      MessageReference ref5 = ms.reference(m5);
+      
+      Delivery del = queue.handle(null, ref1, null);
+      assertFalse(del.isSelectorAccepted());
+      
+      del = queue.handle(null, ref2, null);
+      assertFalse(del.isSelectorAccepted());
+      
+      del = queue.handle(null, ref3, null);
+      assertTrue(del.isSelectorAccepted());
+      
+      del = queue.handle(null, ref4, null);
+      assertFalse(del.isSelectorAccepted());
+      
+      del = queue.handle(null, ref5, null);
+      assertFalse(del.isSelectorAccepted());
+   }
+   
+   
+   public void testUnreliableSynchronousDeliveryTwoReceivers() throws Exception
+   {
+      if (queue.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);
+      
+      queue.getLocalDistributor().add(r1);
+      queue.getLocalDistributor().add(r2);
+      
+      Delivery d = queue.handle(observer, createReference(0, false, "payload"), null);
+      
+      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 (!queue.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(queue.getLocalDistributor().add(r1));
+      assertTrue(queue.getLocalDistributor().add(r2));
+
+      Delivery d = queue.handle(observer, createReference(0, true, "payload"), null);
+
+      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(queue.getLocalDistributor().iterator().hasNext());
+      
+      queue.getLocalDistributor().add(receiver1);
+      
+      assertTrue(queue.getLocalDistributor().contains(receiver1));
+      
+      queue.getLocalDistributor().remove(receiver1);
+      
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+      
+      assertFalse(queue.getLocalDistributor().contains(receiver1));
+      
+      queue.getLocalDistributor().add(receiver1);
+      
+      assertTrue(queue.getLocalDistributor().contains(receiver1));
+      
+      queue.getLocalDistributor().remove(receiver2);
+      
+      assertTrue(queue.getLocalDistributor().contains(receiver1));
+                 
+   }
+
+   public void testClosedChannel() throws Exception
+   {
+      queue.close();
+      try
+      {
+         queue.handle(null, createReference(0), null);
+         fail("should throw exception");
+      }
+      catch(IllegalStateException e)
+      {
+         //OK
+      }
+   }
+
+   public void testHandleNullRoutable() throws Exception
+   {
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+      assertNull(queue.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 (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      List stored = queue.browse(null);
+      assertEquals(1, stored.size());
+
+      Message sm = (Message)stored.iterator().next();
+      assertFalse(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+
+      SimpleReceiver receiver = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
+      queue.getLocalDistributor().add(receiver);
+      queue.deliver();
+      assertEquals(1, receiver.getMessages().size());
+      assertEquals(0, ((Message)receiver.getMessages().get(0)).getMessageID());
+
+      queue.deliver();
+      assertEquals(1, receiver.getMessages().size());
+
+
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_2() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      List stored = queue.browse(null);
+      assertEqualSets(refs, stored);
+
+      SimpleReceiver receiver = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
+      queue.getLocalDistributor().add(receiver);
+      queue.deliver();
+      assertEquals(10, receiver.getMessages().size());
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         assertEquals(i, ((Message)receiver.getMessages().get(i)).getMessageID());         
+      }
+      receiver.clear();
+
+      queue.deliver();
+      assertEquals(0, receiver.getMessages().size());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_3_2() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+      
+      log.trace("ref is reliable:" + ref.getMessage().isReliable());
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      List stored = queue.browse(null);
+      assertEquals(1, stored.size());
+
+      Message sm = (Message)stored.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+
+      queue.deliver();
+
+      SimpleReceiver receiver = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
+      queue.getLocalDistributor().add(receiver);
+      queue.deliver();
+      assertEquals(1, receiver.getMessages().size());
+      assertEquals(0, ((Message)receiver.getMessages().get(0)).getMessageID());
+
+      queue.deliver();
+      assertEquals(1, receiver.getMessages().size());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_4_2() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertEqualSets(refs, queue.browse(null));
+
+      SimpleReceiver receiver = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
+      queue.getLocalDistributor().add(receiver);
+      queue.deliver();
+      assertEquals(10, receiver.getMessages().size());
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         assertEquals(i, ((Message)receiver.getMessages().get(i)).getMessageID());         
+      }
+      receiver.clear();
+
+      queue.deliver();
+      assertEquals(0, receiver.getMessages().size());
+   }
+
+
+
+   //////
+   ////// Transacted send and commit
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_5() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.commit();
+
+      List stored = queue.browse(null);
+      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 (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.commit();
+
+      List stored = queue.browse(null);
+      assertEqualSets(refs, stored);
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_7_2() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.commit();
+
+      List stored = queue.browse(null);
+      assertEquals(1, stored.size());
+
+      Message sm = (Message)stored.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   
+   public void testNonRecoverableChannel_8_1_mixed_1() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES * 2];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         refs[i + NUMBER_OF_MESSAGES] = createReference(i + NUMBER_OF_MESSAGES , true, "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i + NUMBER_OF_MESSAGES], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      try
+      {
+         tx.commit();
+         fail("this should throw exception");
+      }
+      catch(Exception e)
+      {
+         // OK
+      }
+
+      // still no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+   }
+  
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_8_2() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.commit();
+
+      assertEqualSets(refs, queue.browse(null));
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testNonRecoverableChannel_8_2_mixed() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.commit();
+
+      assertEqualSets(refs, queue.browse(null));
+   }
+
+
+   //////
+   ////// Transacted send and rollback
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_9() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_10() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_11() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_12() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testNonRecoverableChannel_12_mixed() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+   }
+
+   ////
+   //// One receiver
+   ////
+
+   //////
+   ////// ACKING receiver
+   //////
+
+   //////
+   ////// Non-transacted send
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_13() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      queue.handle(observer, ref, null);
+
+      assertTrue(queue.browse(null).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 (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertTrue(queue.browse(null).isEmpty());
+
+      List received = r.getMessages();
+      assertEqualSets(refs, received);
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_15_2() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      assertTrue(queue.browse(null).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 accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_16_2() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertTrue(queue.browse(null).isEmpty());
+      assertEqualSets(refs, r.getMessages());
+   }
+
+   //////
+   ////// Transacted send and commit
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_17() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      assertTrue(queue.browse(null).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 (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      assertTrue(queue.browse(null).isEmpty());
+      assertEqualSets(refs, r.getMessages());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+ 
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_19_2() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      List received = r.getMessages();
+      assertEquals(1, received.size());
+      Message sm = (Message)received.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testNonRecoverableChannel_20_1_mixed() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).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, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_20_2() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      assertEqualSets(refs, 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 (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      assertEqualSets(refs, r.getMessages());
+   }
+
+   //////
+   ////// Transacted send and rollback
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_21() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_22() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_23() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_24() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).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 (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).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 (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      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(queue.browse(null).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 (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      r.setImmediateAsynchronousAcknowledgment(true);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      // the receiver should have returned a "done" delivery
+      assertTrue(queue.browse(null).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(queue.browse(null).isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment and commit
+   ////////////
+
+   public void testNonRecoverableChannel_25_1() throws Throwable
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      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);
+
+      deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      tx.commit();
+
+      assertTrue(queue.browse(null).isEmpty());
+      
+      deliveringCount = queue.getDeliveringCount();
+      assertEquals(0, deliveringCount);
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment and rollback
+   ////////////
+
+   public void testNonRecoverableChannel_25_2() throws Throwable
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      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);
+
+      deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      tx.rollback();
+
+      deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      // acknowledge non-transactionally
+      r.acknowledge(ackm, null);
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   ////////////
+   //////////// Non-transacted acknowledgment
+   ////////////
+
+   public void testNonRecoverableChannel_26() throws Throwable
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertEqualSets(refs, r.getMessages());
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(queue.browse(null).isEmpty());
+
+   }
+
+   ////////////
+   //////////// Transacted acknowledgment and commit
+   ////////////
+
+   public void testNonRecoverableChannel_26_1() throws Throwable
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertEqualSets(refs, 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);
+      }
+
+      tx.commit();
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment and rollback
+   ////////////
+
+   public void testNonRecoverableChannel_26_2() throws Throwable
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertEqualSets(refs, 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);
+      }
+
+      tx.rollback();
+
+      // acknowledge non-transactionally
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   ////////////
+   //////////// Non-transacted acknowledgment
+   ////////////
+
+  
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_27_1_2() throws Throwable
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      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(queue.browse(null).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 (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      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);
+
+      deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      tx.commit();
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   ////////////
+   //////////// Non-transacted acknowledgment
+   ////////////
+
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_28_1_2() throws Throwable
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertEqualSets(refs, r.getMessages());
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(queue.browse(null).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 (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertEqualSets(refs, r.getMessages());
+
+      Transaction tx = tr.createTransaction();
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         r.acknowledge(ackm, tx);
+      }
+
+      tx.commit();
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+   //////
+   ////// Transacted send and commit
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_29() throws Throwable
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      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(queue.browse(null).isEmpty());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_30() throws Throwable
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      assertEqualSets(refs, r.getMessages());
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   ///////////
+   /////////// Channel does accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_31_2() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);      
+
+      List received = r.getMessages();
+      assertEquals(1, received.size());
+      Message rm = (Message)received.iterator().next();
+      assertTrue(rm.isReliable());
+      assertEquals(0, rm.getMessageID());
+   }
+
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+  
+   
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_32_2() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(NUMBER_OF_MESSAGES, deliveringCount);
+      
+      assertEqualSets(refs, 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 (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(NUMBER_OF_MESSAGES, deliveringCount);
+      assertEqualSets(refs, r.getMessages());
+   }
+
+
+
+   //////
+   ////// Transacted send and rollback
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_33() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_34() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_35() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_36() throws Exception
+   {
+      if (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).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 (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+
+   ////
+   //// Zero receivers
+   ////
+
+   //////
+   ////// Non-transacted send
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_1() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      List stored = queue.browse(null);
+      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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+
+      }
+
+      assertEqualSets(refs, queue.browse(null));
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_3() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      List stored = queue.browse(null);
+      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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertEqualSets(refs, queue.browse(null));
+
+   }
+
+   //////
+   ////// Transacted send and commit
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_5() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.commit();
+
+      List stored = queue.browse(null);
+      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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.commit();
+
+      assertEqualSets(refs, queue.browse(null));
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_7() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.commit();
+
+      List stored = queue.browse(null);
+      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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.commit();
+
+      assertEqualSets(refs, queue.browse(null));
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testRecoverableChannel_8_mixed() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.commit();
+
+      assertEqualSets(refs, queue.browse(null));
+   }
+
+
+   //////
+   ////// Transacted send and rollback
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_9() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_10() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_11() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_12() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testRecoverableChannel_12_mixed() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+   }
+
+   ////
+   //// One receiver
+   ////
+
+   //////
+   ////// ACKING receiver
+   //////
+
+   //////
+   ////// Non-transacted send
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_13() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      assertTrue(queue.browse(null).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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertTrue(queue.browse(null).isEmpty());
+
+      List received = r.getMessages();
+      assertEqualSets(refs, received);
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_15() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      assertTrue(queue.browse(null).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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertTrue(queue.browse(null).isEmpty());
+      assertEqualSets(refs, r.getMessages());
+   }
+
+   //////
+   ////// Transacted send and commit
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_17() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      assertTrue(queue.browse(null).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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      BrokenReceiver brokenReceiver = new BrokenReceiver(2);
+      assertTrue(queue.getLocalDistributor().add(brokenReceiver));
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      ref = createReference(1, false, "payload");
+
+      log.debug("sending message 2");
+      queue.handle(observer, ref, tx);
+
+      ref = createReference(2, false, "payload");
+
+      log.debug("sending message 3");
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      tx.commit();
+
+      assertEquals(2, queue.browse(null).size());
+      assertEquals(1, brokenReceiver.getMessages().size());
+   }
+
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_18() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      assertTrue(queue.browse(null).isEmpty());
+      assertEqualSets(refs, r.getMessages());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_19() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      assertEqualSets(refs, 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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      assertEqualSets(refs, r.getMessages());
+   }
+
+
+   //////
+   ////// Transacted send and rollback
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_21() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_22() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_23() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_24() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+      
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      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(queue.browse(null).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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      r.setImmediateAsynchronousAcknowledgment(true);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      // the receiver should have returned a "done" delivery
+      assertTrue(queue.browse(null).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(queue.browse(null).isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment and commit
+   ////////////
+
+   public void testRecoverableChannel_25_1() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      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);
+
+      deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      tx.commit();
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment and rollback
+   ////////////
+
+   public void testRecoverableChannel_25_2() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      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);
+
+      deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      tx.rollback();
+
+      deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      // acknowledge non-transactionally
+      r.acknowledge(ackm, null);
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   ////////////
+   //////////// Non-transacted acknowledgment
+   ////////////
+
+   public void testRecoverableChannel_26() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
+      assertEqualSets(refs, r.getMessages());
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(queue.browse(null).isEmpty());
+
+   }
+
+   ////////////
+   //////////// Transacted acknowledgment and commit
+   ////////////
+
+   public void testRecoverableChannel_26_1() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
+      assertEqualSets(refs, 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);
+      }
+
+      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
+
+      tx.commit();
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment and rollback
+   ////////////
+
+   public void testRecoverableChannel_26_2() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
+      assertEqualSets(refs, 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);
+      }
+
+      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
+
+      tx.rollback();
+
+      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
+
+      // acknowledge non-transactionally
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   ////////////
+   //////////// Non-transacted acknowledgment
+   ////////////
+
+   public void testRecoverableChannel_27() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      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(queue.browse(null).isEmpty());
+   }
+
+   /**
+    * Test duplicate acknowledgment.
+    */
+   public void testRecoverableChannel_27_Duplicate_ACK() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      queue.handle(observer, ref, null);
+
+      Message ackm = (Message)r.getMessages().get(0);
+
+      // acknowledge once
+      r.acknowledge(ackm, null);
+
+      assertTrue(queue.browse(null).isEmpty());
+
+      // acknowledge twice
+      try
+      {
+         r.acknowledge(ackm, null);
+      }
+      catch(IllegalStateException e)
+      {
+         // OK
+      }
+
+      assertTrue(queue.browse(null).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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      r.setImmediateAsynchronousAcknowledgment(true);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      // the receiver should have returned a "done" delivery
+      assertTrue(queue.browse(null).isEmpty());
+
+      List messages = r.getMessages();
+      assertEquals(1, messages.size());
+      Message ackm = (Message)messages.get(0);
+      assertEquals(0, ackm.getMessageID());
+
+      // Acknowledgment handling implemenation is NOT idempotent, the channel DOES NOT allow
+      // extraneous duplicate acknowlegments, so we test for that.
+
+      try
+      {
+         r.acknowledge(ackm, null);
+      }
+      catch(IllegalStateException e)
+      {
+         // OK
+         log.trace(e);
+
+      }
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment and commit
+   ////////////
+
+   public void testRecoverableChannel_27_1() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      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);
+
+      deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      tx.commit();
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment and rollback
+   ////////////
+
+   public void testRecoverableChannel_27_2() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      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);
+
+      deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      tx.rollback();
+
+      deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      // acknowledge non-transactionally
+      r.acknowledge(ackm, null);
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   ////////////
+   //////////// Non-transacted acknowledgment
+   ////////////
+
+   public void testRecoverableChannel_28() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
+      
+      assertEqualSets(refs, r.getMessages());
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+   ////////////
+   //////////// Transacted acknowledgment and commit
+   ////////////
+
+   public void testRecoverableChannel_28_1() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
+      assertEqualSets(refs, 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);
+      }
+
+      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
+
+      tx.commit();
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+   ////////////
+   //////////// Transacted acknowledgment and rollback
+   ////////////
+
+   public void testRecoverableChannel_28_2() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = queue.handle(observer, refs[i], null);
+      }
+
+      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
+      assertEqualSets(refs, 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);
+      }
+
+      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
+
+      tx.rollback();
+
+      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
+
+      // acknowledge non-transactionally
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+
+   //////
+   ////// Transacted send and commit
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_29() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      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(queue.browse(null).isEmpty());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_30() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
+      assertEqualSets(refs, r.getMessages());
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_31() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      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(queue.browse(null).isEmpty());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_32() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+      
+      
+      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
+      assertEqualSets(refs, r.getMessages());
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testRecoverableChannel_32_mixed() throws Throwable
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+      
+      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
+      assertEqualSets(refs, r.getMessages());
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(queue.browse(null).isEmpty());
+   }
+
+
+   //////
+   ////// Transacted send and rollback
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_33() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_34() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_35() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      MessageReference ref = createReference(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
+      queue.handle(observer, ref, tx);
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_36() throws Exception
+   {
+      if (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         refs[i] = createReference(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
+      assertTrue(queue.getLocalDistributor().add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         queue.handle(observer, refs[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, queue.browse(null).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 (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-recoverable channel, non-reliable message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      List stored = queue.browse(null);
+      assertEquals(1, stored.size());
+
+
+      SimpleReceiver receiver = new SimpleReceiver("BrokenReceiver", SimpleReceiver.BROKEN);
+      assertTrue(queue.getLocalDistributor().add(receiver));
+
+      stored = queue.browse(null);
+      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 (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-recoverable channel, non-reliable message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      List stored = queue.browse(null);
+      assertEquals(1, stored.size());
+
+      SimpleReceiver receiver =
+            new SimpleReceiver("ACKINGReceiver", SimpleReceiver.ACKING, queue);
+      assertTrue(queue.getLocalDistributor().add(receiver));
+
+      assertEquals(1, queue.browse(null).size());
+
+      // receiver explicitely asks for message
+      receiver.requestMessages();
+
+      assertTrue(queue.browse(null).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 (queue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-recoverable channel, non-reliable message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      List stored = queue.browse(null);
+      assertEquals(1, stored.size());
+
+      SimpleReceiver receiver =
+            new SimpleReceiver("NACKINGReceiver", SimpleReceiver.ACCEPTING, queue);
+      assertTrue(queue.getLocalDistributor().add(receiver));
+
+      assertEquals(1, queue.browse(null).size());
+
+      // receiver explicitely asks for message
+      receiver.requestMessages();
+
+      int deliveringCount = queue.getDeliveringCount();
+      assertEquals(1, deliveringCount);
+
+      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(queue.browse(null).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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-recoverable channel, non-reliable message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      List stored = queue.browse(null);
+      assertEquals(1, stored.size());
+
+
+      SimpleReceiver receiver = new SimpleReceiver("BrokenReceiver", SimpleReceiver.BROKEN);
+      assertTrue(queue.getLocalDistributor().add(receiver));
+
+      stored = queue.browse(null);
+      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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-recoverable channel, non-reliable message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      List stored = queue.browse(null);
+      assertEquals(1, stored.size());
+
+      SimpleReceiver receiver =
+            new SimpleReceiver("ACKINGReceiver", SimpleReceiver.ACKING, queue);
+      assertTrue(queue.getLocalDistributor().add(receiver));
+
+      // receiver explicitely asks for message
+      receiver.requestMessages();
+
+      assertTrue(queue.browse(null).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 (!queue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+
+      MessageReference ref = createReference(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-recoverable channel, non-reliable message
+      Delivery delivery = queue.handle(observer, ref, null);
+
+      List stored = queue.browse(null);
+      assertEquals(1, stored.size());
+
+      SimpleReceiver receiver =
+            new SimpleReceiver("NACKINGReceiver", SimpleReceiver.ACCEPTING, queue);
+      assertTrue(queue.getLocalDistributor().add(receiver));
+
+      assertEquals(1, queue.browse(null).size());
+
+      // receiver explicitely asks for message
+      receiver.requestMessages();
+
+      assertEquals(1, queue.getDeliveringCount());
+
+      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(queue.browse(null).isEmpty());
+
+      messages = receiver.getMessages();
+      assertEquals(1, messages.size());
+      sm = (Message)messages.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   // Distributor tests ---------------------------------------------
+
+   public void testAddOneReceiver()
+   {
+      Receiver r = new SimpleReceiver("ONE");
+
+      assertTrue(queue.getLocalDistributor().add(r));
+      assertFalse(queue.getLocalDistributor().add(r));
+
+      assertTrue(queue.getLocalDistributor().contains(r));
+
+      Iterator i = queue.getLocalDistributor().iterator();
+      assertEquals(r, i.next());
+      assertFalse(i.hasNext());
+
+      queue.getLocalDistributor().clear();
+      assertFalse(queue.getLocalDistributor().iterator().hasNext());
+   }
+
+   public void testRemoveInexistentReceiver()
+   {
+      assertFalse(queue.getLocalDistributor().remove(new SimpleReceiver("INEXISTENT")));
+   }
+
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+
+//   protected abstract void crashChannel() throws Exception;
+//
+//   protected abstract void recoverChannel() throws Exception;
+
+   // Private -------------------------------------------------------
+   
+   private MessageReference createReference(long id, boolean reliable, Serializable payload)
+   {
+      return ms.reference(CoreMessageFactory.createCoreMessage(id, reliable, payload));
+   }
+   
+   private MessageReference createReference(long id)
+   {
+      return ms.reference(CoreMessageFactory.createCoreMessage(id));
+   }
+   
+   // Inner classes -------------------------------------------------
+
+}

Added: trunk/tests/src/org/jboss/test/messaging/core/NonRecoverableMessagingQueueTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/NonRecoverableMessagingQueueTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/NonRecoverableMessagingQueueTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,75 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.messaging.core;
+
+import org.jboss.messaging.core.impl.MessagingQueue;
+
+/**
+ * @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: 2386 $</tt>
+ *
+ * $Id: NonRecoverablePagingFilteredQueueTest.java 2386 2007-02-21 18:07:44Z timfox $
+ */
+public class NonRecoverableMessagingQueueTest extends MessagingQueueTestBase
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+
+  
+   // Constructors --------------------------------------------------
+
+   public NonRecoverableMessagingQueueTest(String name)
+   {
+      super(name);
+   }
+
+   // ChannelTestBase overrides  ------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();
+      
+      queue = new MessagingQueue(1, "queue1", 1, ms, pm, false, -1, null, false, false);
+      queue.activate();
+   }
+   
+   public void tearDown() throws Exception
+   {
+      queue.close();
+      super.tearDown();
+   }
+
+   // Public --------------------------------------------------------
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------   
+}
+

Copied: trunk/tests/src/org/jboss/test/messaging/core/PostOfficeTestBase.java (from rev 2781, trunk/tests/src/org/jboss/test/messaging/core/plugin/base/PostOfficeTestBase.java)
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/PostOfficeTestBase.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/PostOfficeTestBase.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,292 @@
+/*
+  * 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 java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.messaging.core.contract.ClusterNotifier;
+import org.jboss.messaging.core.contract.Condition;
+import org.jboss.messaging.core.contract.ConditionFactory;
+import org.jboss.messaging.core.contract.FailoverMapper;
+import org.jboss.messaging.core.contract.FilterFactory;
+import org.jboss.messaging.core.contract.JChannelFactory;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.PersistenceManager;
+import org.jboss.messaging.core.contract.PostOffice;
+import org.jboss.messaging.core.contract.Queue;
+import org.jboss.messaging.core.impl.DefaultClusterNotifier;
+import org.jboss.messaging.core.impl.IDManager;
+import org.jboss.messaging.core.impl.JDBCPersistenceManager;
+import org.jboss.messaging.core.impl.message.SimpleMessageStore;
+import org.jboss.messaging.core.impl.postoffice.DefaultFailoverMapper;
+import org.jboss.messaging.core.impl.postoffice.MessagingPostOffice;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.core.impl.tx.TransactionRepository;
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.core.plugin.postoffice.ClusteredPersistenceServiceConfigFileJChannelFactory;
+import org.jboss.test.messaging.tools.ServerManagement;
+import org.jboss.test.messaging.tools.jmx.ServiceContainer;
+import org.jboss.test.messaging.util.CoreMessageFactory;
+
+/**
+ * 
+ * A PostOfficeTestBase
+ *
+ * @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$</tt>
+ *
+ * $Id$
+ *
+ */
+public class PostOfficeTestBase extends MessagingTestCase
+{
+   // Constants ------------------------------------------------------------------------------------
+
+   // Static ---------------------------------------------------------------------------------------
+	
+   protected static PostOffice createClusteredPostOffice(int nodeID,   		
+			                                                String groupName,
+			                                                long stateTimeout,
+			                                                long castTimeout,
+			                                                ServiceContainer sc,
+			                                                MessageStore ms,			                                         
+			                                                TransactionRepository tr,
+			                                                PersistenceManager pm)
+      throws Exception
+   {
+      FilterFactory ff = new SimpleFilterFactory();
+      FailoverMapper mapper = new DefaultFailoverMapper();
+      ConditionFactory cf = new SimpleConditionFactory();
+      IDManager idm = new IDManager("channel_id", 10, pm);
+      idm.start();
+      ClusterNotifier cn = new DefaultClusterNotifier();
+
+      // we're testing with JGroups stack configurations we're shipping with the release
+
+      String configFilePath = sc.getPersistenceConfigFile(true);
+
+      // TODO (ovidiu) we're temporarily ignoring the multiplex option, it doesn't work well
+      boolean ignoreMultiplexer = true;
+      JChannelFactory jChannelFactory =
+         new ClusteredPersistenceServiceConfigFileJChannelFactory(configFilePath,
+                                                                  ignoreMultiplexer,
+                                                                  sc.getMBeanServer());
+
+      MessagingPostOffice postOffice =
+         new MessagingPostOffice(sc.getDataSource(), sc.getTransactionManager(),
+                                 sc.getPostOfficeSQLProperties(), true, nodeID,
+                                 "Clustered", ms, pm, tr, ff, cf, idm, cn,
+                                 groupName, jChannelFactory,
+                                 stateTimeout, castTimeout, mapper);
+      
+      postOffice.start();
+
+      return postOffice;
+   }
+   
+   protected static PostOffice createNonClusteredPostOffice(ServiceContainer sc, MessageStore ms, TransactionRepository tr,
+   		                                                   PersistenceManager pm)
+   	throws Exception
+   {
+   	FilterFactory ff = new SimpleFilterFactory();
+   	ConditionFactory cf = new SimpleConditionFactory();
+      IDManager idm = new IDManager("channel_id", 10, pm);
+      ClusterNotifier cn = new DefaultClusterNotifier();
+
+   	MessagingPostOffice postOffice =
+   		new MessagingPostOffice(sc.getDataSource(), sc.getTransactionManager(),
+   				                  sc.getPostOfficeSQLProperties(),
+   									   true, 1, "NonClustered", ms, pm, tr, ff, cf, idm, cn);
+
+   	postOffice.start();
+
+   	return postOffice;
+   }   
+
+   // Attributes -----------------------------------------------------------------------------------
+
+   protected ServiceContainer sc;
+
+   protected IDManager channelIDManager;
+   
+   protected IDManager transactionIDManager;
+   
+   protected PersistenceManager pm;
+      
+   protected MessageStore ms;
+   
+   protected TransactionRepository tr;
+   
+   protected ConditionFactory conditionFactory;
+   
+   private static long msgCount;
+   
+   
+   // Constructors --------------------------------------------------
+
+   public PostOfficeTestBase(String name)
+   {
+      super(name);
+   }
+
+   // Public --------------------------------------------------------
+   
+   // Protected --------------------------------------------------------
+   
+	protected PostOffice createNonClusteredPostOffice() throws Exception
+	{
+		return createNonClusteredPostOffice(sc, ms, tr, pm);
+	}
+	
+	protected PostOffice createClusteredPostOffice(int nodeID, String groupName,
+			                                         long stateTimeout, long castTimeout) throws Exception
+	{
+		return createClusteredPostOffice(nodeID, groupName, stateTimeout, castTimeout, sc, ms, tr, pm);
+	}
+	
+	protected PostOffice createClusteredPostOffice(int nodeID, String groupName) throws Exception
+   {
+		return createClusteredPostOffice(nodeID, groupName, 5000, 5000, sc, ms, tr, pm);
+   }
+   
+   protected List sendMessages(String conditionText, boolean persistent, PostOffice office, int num, Transaction tx) throws Exception
+   {
+      List list = new ArrayList();
+      
+      for (int i = 0; i < num; i++)
+      {         
+         Message msg = CoreMessageFactory.createCoreMessage(msgCount++, persistent, null);      
+         
+         MessageReference ref = ms.reference(msg);         
+         
+         Condition condition = conditionFactory.createCondition(conditionText);
+         
+         boolean routed = office.route(ref, condition, null);         
+         
+         assertTrue(routed);
+         
+         list.add(msg);
+      }
+      
+      Thread.sleep(1000);
+      
+      return list;
+   }
+   
+   protected void checkContainsAndAcknowledge(Message msg, SimpleReceiver receiver, Queue queue) throws Throwable
+   {
+      List msgs = receiver.getMessages();
+      assertNotNull(msgs);
+      assertEquals(1, msgs.size());
+      Message msgRec = (Message)msgs.get(0);
+      assertEquals(msg.getMessageID(), msgRec.getMessageID());
+      receiver.acknowledge(msgRec, null);
+      msgs = queue.browse(null);
+      assertNotNull(msgs);
+      assertTrue(msgs.isEmpty()); 
+      receiver.clear();
+   }
+   
+   protected void checkContainsAndAcknowledge(List msgList, SimpleReceiver receiver, Queue queue) throws Throwable
+   {
+      List msgs = receiver.getMessages();
+      assertNotNull(msgs);
+      assertEquals(msgList.size(), msgs.size());
+      
+      for (int i = 0; i < msgList.size(); i++)
+      {
+         Message msgRec = (Message)msgs.get(i);
+         Message msgCheck = (Message)msgList.get(i);
+         assertEquals(msgCheck.getMessageID(), msgRec.getMessageID());
+         receiver.acknowledge(msgRec, null);
+      }
+      
+      msgs = queue.browse(null);
+      assertNotNull(msgs);
+      assertTrue(msgs.isEmpty()); 
+      receiver.clear();
+   }
+   
+   protected void checkEmpty(SimpleReceiver receiver) throws Throwable
+   {
+      List msgs = receiver.getMessages();
+      assertNotNull(msgs);
+      assertTrue(msgs.isEmpty());
+   }
+
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+
+      sc = new ServiceContainer("all");
+
+      sc.start();
+
+      pm =
+         new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager(),
+                  sc.getPersistenceManagerSQLProperties(),
+                  true, true, true, false, 100);
+      pm.start();
+
+      transactionIDManager = new IDManager("TRANSACTION_ID", 10, pm);
+      transactionIDManager.start();
+
+      ms = new SimpleMessageStore();
+      ms.start();
+
+      tr = new TransactionRepository(pm, ms, transactionIDManager);
+      tr.start();
+
+      channelIDManager = new IDManager("CHANNEL_ID", 10, pm);
+      channelIDManager.start();
+
+      conditionFactory = new SimpleConditionFactory();
+
+      log.debug("setup done");
+   }
+
+   protected void tearDown() throws Exception
+   {
+      if (!ServerManagement.isRemote())
+      {
+         sc.stop();
+         sc = null;
+      }
+      pm.stop();
+      tr.stop();
+      ms.stop();
+      transactionIDManager.stop();
+      channelIDManager.stop();
+
+      super.tearDown();
+   }
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+}
+
+

Added: trunk/tests/src/org/jboss/test/messaging/core/RecoverableMessagingQueueTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/RecoverableMessagingQueueTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/RecoverableMessagingQueueTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,73 @@
+/*
+* 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.messaging.core.impl.MessagingQueue;
+
+/**
+ * @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 RecoverableMessagingQueueTest extends MessagingQueueTestBase
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+
+   // Constructors --------------------------------------------------
+
+   public RecoverableMessagingQueueTest(String name)
+   {
+      super(name);
+   }
+
+   // ChannelTestBase overrides  ------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();
+      
+      queue = new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, false, false);
+      queue.activate();
+   }
+
+   public void tearDown() throws Exception
+   {
+      queue.close();
+      super.tearDown();
+   }
+
+   // Public --------------------------------------------------------
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------   
+}

Added: trunk/tests/src/org/jboss/test/messaging/core/RoundRobinDistributorTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/RoundRobinDistributorTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/RoundRobinDistributorTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,562 @@
+/*
+* 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.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.DeliveryObserver;
+import org.jboss.messaging.core.contract.Distributor;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.Receiver;
+import org.jboss.messaging.core.impl.RoundRobinDistributor;
+import org.jboss.messaging.core.impl.SimpleDelivery;
+import org.jboss.messaging.core.impl.message.SimpleMessageStore;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.util.CoreMessageFactory;
+
+/**
+ * @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 $</tt>
+ * $Id: $
+ */
+public class RoundRobinDistributorTest extends MessagingTestCase
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   protected MessageStore ms;
+
+   // Constructors --------------------------------------------------
+
+   public RoundRobinDistributorTest(String name)
+   {
+      super(name);
+   }
+
+   // ChannelTestBase overrides  ------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();
+      
+      ms = new SimpleMessageStore();
+      
+      ms.start();
+   }
+
+   public void tearDown() throws Exception
+   {
+      super.tearDown();
+      
+      ms.stop();
+   }
+
+   // Public --------------------------------------------------------
+   
+   public void testAllAccepting()
+   {
+      Distributor distributor = new RoundRobinDistributor();
+      
+      final int numReceivers = 10;
+      
+      SimpleReceiver[] receivers = new SimpleReceiver[numReceivers];
+      
+      for (int i = 0; i < numReceivers; i++)
+      {
+         receivers[i] = new SimpleReceiver();
+         
+         distributor.add(receivers[i]);
+      }
+      
+      Message msg = CoreMessageFactory.createCoreMessage(123, true, null);
+      
+      MessageReference ref = ms.reference(msg);
+            
+      Delivery del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 0);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 1);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 2);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 3);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 4);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 5);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 6);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 7);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 8);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 9);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 0);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 1);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 2);
+      resetReceivers(receivers);
+      
+   }
+   
+   public void testSomeClosed()
+   {
+      Distributor distributor = new RoundRobinDistributor();
+      
+      final int numReceivers = 10;
+      
+      SimpleReceiver[] receivers = new SimpleReceiver[numReceivers];
+      
+      for (int i = 0; i < numReceivers; i++)
+      {
+         receivers[i] = new SimpleReceiver();
+         
+         distributor.add(receivers[i]);
+      }
+      
+      receivers[2].closed = true;
+      
+      receivers[5].closed = true;
+      receivers[6].closed = true;
+      
+      receivers[9].closed = true;
+      
+      Message msg = CoreMessageFactory.createCoreMessage(123, true, null);
+      
+      MessageReference ref = ms.reference(msg);
+      
+      Delivery del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 0);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 1);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 3);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 4);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 7);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 8);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 0);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 1);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 3);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 4);
+      resetReceivers(receivers);
+      
+      
+   }
+   
+   public void testAllClosed()
+   {
+      Distributor distributor = new RoundRobinDistributor();
+      
+      final int numReceivers = 10;
+      
+      SimpleReceiver[] receivers = new SimpleReceiver[numReceivers];
+      
+      for (int i = 0; i < numReceivers; i++)
+      {
+         receivers[i] = new SimpleReceiver();
+         
+         receivers[i].closed = true;
+         
+         distributor.add(receivers[i]);
+      }
+      
+      
+      Message msg = CoreMessageFactory.createCoreMessage(123, true, null);
+      
+      MessageReference ref = ms.reference(msg);
+      
+      Delivery del = distributor.handle(null, ref, null);
+      assertNull(del);
+
+      del = distributor.handle(null, ref, null);
+      assertNull(del);
+      
+      del = distributor.handle(null, ref, null);
+      assertNull(del);
+
+      
+      
+   }
+   
+   public void testSomeNoSelectorMatch()
+   {
+      Distributor distributor = new RoundRobinDistributor();
+      
+      final int numReceivers = 10;
+      
+      SimpleReceiver[] receivers = new SimpleReceiver[numReceivers];
+      
+      for (int i = 0; i < numReceivers; i++)
+      {
+         receivers[i] = new SimpleReceiver();
+         
+         distributor.add(receivers[i]);
+      }
+      
+      receivers[2].selectorMatches = false;
+      
+      receivers[5].selectorMatches = false;
+      receivers[6].selectorMatches = false;
+      
+      receivers[9].selectorMatches = false;
+      
+      Message msg = CoreMessageFactory.createCoreMessage(123, true, null);
+      
+      MessageReference ref = ms.reference(msg);
+      
+      Delivery del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 0);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 1);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 3);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 4);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 7);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 8);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 0);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 1);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 3);
+      resetReceivers(receivers);
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      checkReceiverGotRef(receivers, 4);
+      resetReceivers(receivers);
+      
+   }
+   
+   public void testAllNoSelectorMatch()
+   {
+      Distributor distributor = new RoundRobinDistributor();
+      
+      final int numReceivers = 10;
+      
+      SimpleReceiver[] receivers = new SimpleReceiver[numReceivers];
+      
+      for (int i = 0; i < numReceivers; i++)
+      {
+         receivers[i] = new SimpleReceiver();
+         
+         receivers[i].selectorMatches = false;
+         
+         distributor.add(receivers[i]);
+      }
+      
+      
+      Message msg = CoreMessageFactory.createCoreMessage(123, true, null);
+      
+      MessageReference ref = ms.reference(msg);
+      
+      Delivery del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      assertFalse(del.isSelectorAccepted());
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      assertFalse(del.isSelectorAccepted());
+      
+      del = distributor.handle(null, ref, null);
+      assertNotNull(del);
+      assertFalse(del.isSelectorAccepted());
+           
+   }
+   
+   public void testNoReceivers()
+   {
+      Distributor distributor = new RoundRobinDistributor();
+
+      Message msg = CoreMessageFactory.createCoreMessage(123, true, null);
+      
+      MessageReference ref = ms.reference(msg);
+      
+      Delivery del = distributor.handle(null, ref, null);
+      assertNull(del);
+      
+      del = distributor.handle(null, ref, null);
+      assertNull(del);
+      
+      del = distributor.handle(null, ref, null);
+      assertNull(del);    
+   }
+
+
+   /**
+    * http://jira.jboss.org/jira/browse/JBMESSAGING-491
+    */
+   public void testDeadlock() throws Exception
+   {
+      final Distributor distributor = new RoundRobinDistributor();
+
+      LockingReceiver receiver = new LockingReceiver();
+      distributor.add(receiver);
+
+      final Thread t = new Thread(new Runnable()
+      {
+         public void run()
+         {
+            // sends the message to the router on a separate thread
+            
+            Message msg = CoreMessageFactory.createCoreMessage(123, true, null);
+            
+            MessageReference ref = ms.reference(msg);
+            
+            distributor.handle(null, ref, null);
+         }
+      }, "Message sending thread");
+
+      // start the sending tread, which will immediately grab the router's "receivers" lock, and it
+      // will sleep for 3 seconds before attempting to grab LockingReceiver's lock.
+      t.start();
+
+
+      // in the mean time, the main thread immediately grabs receiver's lock ...
+
+      synchronized(receiver.getLock())
+      {
+         // ... sleeps for 500 ms to allow sender thread time to grab router's "receivers" lock
+         Thread.sleep(500);
+
+         // ... and try to remove the receiver form router
+         distributor.remove(receiver);
+      }
+
+      // normally, receiver removal should be immediate, as the router releases receiver's lock
+      // immediately, so test should complete. Pre-JBMESSAGING-491, the test deadlocks.
+   }
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+
+   protected void checkReceiverGotRef(SimpleReceiver[] receivers, int pos)
+   {
+      for (int i = 0; i < receivers.length; i++)
+      {
+         SimpleReceiver r = receivers[i];
+
+         if (i == pos)
+         {
+            assertTrue(r.gotRef);
+         }
+         else
+         {
+            assertFalse(r.gotRef);
+         }
+      }
+   }
+
+   protected void resetReceivers(SimpleReceiver[] receivers)
+   {
+      for (int i = 0; i < receivers.length; i++)
+      {
+         SimpleReceiver r = receivers[i];
+
+         r.gotRef = false;
+      }
+   }
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------  
+   
+   class LockingReceiver implements Receiver
+   {
+      private Object lock;
+
+      public LockingReceiver()
+      {
+         lock = new Object();
+      }
+
+      public Delivery handle(DeliveryObserver observer, MessageReference ref, Transaction tx)
+      {
+         // The delivering thread needs to grab the receiver's lock to complete delivery; this
+         // is how Messaging receivers are written, anyway. We simulate the race condition by
+         // putting the sending thread to sleep for 3 seconds before allowing it to attempt to
+         // grab the lock
+
+         try
+         {
+            Thread.sleep(3000);
+         }
+         catch(InterruptedException e)
+         {
+            // this shouldn't happen in the test
+            return null;
+         }
+
+         synchronized(lock)
+         {
+            return new SimpleDelivery(null, null, true);
+         }
+      }
+
+      public Object getLock()
+      {
+         return lock;
+      }
+   }
+   
+   class SimpleReceiver implements Receiver
+   {
+      boolean selectorMatches = true;
+      
+      boolean closed;
+      
+      boolean gotRef;
+
+      public Delivery handle(DeliveryObserver observer, MessageReference ref, Transaction tx)
+      {
+         if (closed)
+         {
+            return null;
+         }
+         
+         Delivery del = new SimpleDelivery(null, null, selectorMatches);
+         
+         if (selectorMatches)
+         {
+            gotRef = true;
+         }
+                  
+         return del;
+      }
+      
+   }
+
+
+   
+
+}
+

Modified: trunk/tests/src/org/jboss/test/messaging/core/SimpleChannel.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleChannel.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleChannel.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -5,21 +5,20 @@
  * See terms of license at gnu.org.
  */
 
-
 package org.jboss.test.messaging.core;
 
 import java.util.Iterator;
 import java.util.List;
 
 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.Receiver;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.tx.Transaction;
+import org.jboss.messaging.core.contract.Channel;
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.DeliveryObserver;
+import org.jboss.messaging.core.contract.Filter;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.Receiver;
+import org.jboss.messaging.core.impl.tx.Transaction;
 import org.jboss.messaging.util.NotYetImplementedException;
 
 /**

Modified: trunk/tests/src/org/jboss/test/messaging/core/SimpleCondition.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleCondition.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleCondition.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -21,8 +21,7 @@
  */
 package org.jboss.test.messaging.core;
 
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.contract.Condition;
+import org.jboss.messaging.core.contract.Condition;
 
 /**
  * A SimpleCondition
@@ -42,11 +41,6 @@
       this.name = name;
    }
 
-   public boolean matches(Condition routingCondition, MessageReference ref)
-   {
-      return equals(routingCondition);            
-   }
-
    public String toText()
    {
       return name;

Modified: trunk/tests/src/org/jboss/test/messaging/core/SimpleConditionFactory.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleConditionFactory.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleConditionFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -21,8 +21,8 @@
  */
 package org.jboss.test.messaging.core;
 
-import org.jboss.messaging.core.plugin.contract.Condition;
-import org.jboss.messaging.core.plugin.contract.ConditionFactory;
+import org.jboss.messaging.core.contract.Condition;
+import org.jboss.messaging.core.contract.ConditionFactory;
 
 /**
  * A SimpleConditionFactory

Modified: trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryObserver.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryObserver.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryObserver.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -21,9 +21,9 @@
 */
 package org.jboss.test.messaging.core;
 
-import org.jboss.messaging.core.DeliveryObserver;
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.tx.Transaction;
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.DeliveryObserver;
+import org.jboss.messaging.core.impl.tx.Transaction;
 import org.jboss.logging.Logger;
 
 /**
@@ -85,11 +85,6 @@
    {
       try
       {
-         if (delivery.isDone())
-         {
-            return true;
-         }
-
          if (toBeAcknowledged != null)
          {
             throw new IllegalStateException("already waiting for another delivery acknowlegment");

Deleted: trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,137 +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.messaging.core.Delivery;
-import org.jboss.messaging.core.DeliveryObserver;
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.message.SimpleMessageStore;
-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 MessagingTestCase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-   protected DeliveryObserver observer;
-   
-   protected Delivery delivery;
-
-   // Constructors --------------------------------------------------
-
-   public SimpleDeliveryTest(String name)
-   {
-      super(name);
-   }
-
-   // ChannelTestBase overrides  ------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-
-      observer = new SimpleDeliveryObserver();
-      delivery = new SimpleDelivery(observer, null, false);
-
-      log.debug("setup done");
-   }
-
-   public void tearDown() throws Exception
-   {
-      delivery = null;
-      observer = null;
-      super.tearDown();
-   }
-
-   // Public --------------------------------------------------------
-   
-   public void testAcknowledgment() throws Throwable
-   {
-      assertFalse(delivery.isDone());
-
-      delivery.acknowledge(null);
-
-      assertTrue(delivery.isDone());
-   }
-   
-   public void testDoneIsSetWithTransaction() throws Throwable
-   {
-      //Calling acknowledge on a SimpleDelivery
-      //Should always result in done being set to true,
-      //even if there is a transaction present.
-      //Otherwise we can end up with a race condition where
-      //the message is acked when still in flight then added
-      //when handle is returned.
-      
-      assertFalse(delivery.isDone());
-      
-      ServiceContainer sc = new ServiceContainer("all,-remoting,-security");
-      sc.start();
-      
-      PersistenceManager pm =
-         new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager(),
-                  sc.getPersistenceManagerSQLProperties(),
-                  true, true, true, false, 100);
-      pm.start();
-      
-      IDManager idm = new IDManager("TRANSACTION_ID", 10, pm);
-      idm.start();
-      
-      TransactionRepository tr = new TransactionRepository(pm, new SimpleMessageStore(), idm);
-      tr.start();
-      
-      Transaction tx = tr.createTransaction();
-      
-      ((SimpleDelivery)delivery).acknowledge(tx);
-      
-      assertTrue(delivery.isDone());
-      
-      pm.stop();
-      tr.stop();
-      
-      sc.stop();
-   }
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Modified: trunk/tests/src/org/jboss/test/messaging/core/SimpleFilter.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleFilter.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleFilter.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -21,8 +21,8 @@
  */
 package org.jboss.test.messaging.core;
 
-import org.jboss.messaging.core.Filter;
-import org.jboss.messaging.core.message.Message;
+import org.jboss.messaging.core.contract.Filter;
+import org.jboss.messaging.core.contract.Message;
 
 /**
  * A SimpleFilter

Modified: trunk/tests/src/org/jboss/test/messaging/core/SimpleFilterFactory.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleFilterFactory.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleFilterFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -21,8 +21,8 @@
  */
 package org.jboss.test.messaging.core;
 
-import org.jboss.messaging.core.Filter;
-import org.jboss.messaging.core.FilterFactory;
+import org.jboss.messaging.core.contract.Filter;
+import org.jboss.messaging.core.contract.FilterFactory;
 
 /**
  * A SimpleFilterFactory

Copied: trunk/tests/src/org/jboss/test/messaging/core/SimpleMessageStoreTest.java (from rev 2781, trunk/tests/src/org/jboss/test/messaging/core/plugin/SimpleMessageStoreTest.java)
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleMessageStoreTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleMessageStoreTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,78 @@
+/*
+* 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.logging.Logger;
+import org.jboss.messaging.core.impl.message.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

Modified: trunk/tests/src/org/jboss/test/messaging/core/SimpleReceiver.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleReceiver.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleReceiver.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -26,15 +26,15 @@
 import java.util.List;
 
 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.Receiver;
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.messaging.core.tx.TxCallback;
+import org.jboss.messaging.core.contract.Channel;
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.DeliveryObserver;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.Receiver;
+import org.jboss.messaging.core.impl.SimpleDelivery;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.core.impl.tx.TxCallback;
 import org.jboss.util.id.GUID;
 
 /**
@@ -120,6 +120,8 @@
    public Delivery handle(DeliveryObserver observer, MessageReference ref, Transaction tx)
    {
       log.trace(this + " got routable:" + ref);
+      
+      log.info(this + " got routable:" + ref);
           
       try
       {
@@ -132,7 +134,7 @@
          if (SELECTOR_REJECTING.equals(state))
          {
             log.trace(this + " is rejecting message since doesn't match selector");
-            return new SimpleDelivery(null, null, true, false);
+            return new SimpleDelivery(null, null, false);
          }
 
          if (REJECTING.equals(state))
@@ -166,7 +168,7 @@
          
          Message m = ref.getMessage();
          
-         SimpleDelivery delivery = new SimpleDelivery(observer, ref, done);
+         SimpleDelivery delivery = new SimpleDelivery(observer, ref, true);
          messages.add(new Object[] {m, done ? null : delivery});
          
          if (immediateAsynchronousAcknowledgment)
@@ -355,7 +357,7 @@
 
    public String toString()
    {
-      return "Receiver["+ name +"](" + state + ")";
+      return "Receiver["+ name +":" + System.identityHashCode(this) + "](" + state + ")";
    }
 
    // Package protected ---------------------------------------------

Deleted: trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverablePagingFilteredQueueTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverablePagingFilteredQueueTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverablePagingFilteredQueueTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,85 +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.PagingFilteredQueue;
-import org.jboss.test.messaging.core.local.base.PagingFilteredQueueTestBase;
-
-/**
- * @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 NonRecoverablePagingFilteredQueueTest extends PagingFilteredQueueTestBase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-  
-   // Constructors --------------------------------------------------
-
-   public NonRecoverablePagingFilteredQueueTest(String name)
-   {
-      super(name);
-   }
-
-   // ChannelTestBase overrides  ------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-      
-      queue = new PagingFilteredQueue("queue1", 1, ms, pm, true, false, -1, null);
-   }
-   
-   public void tearDown() throws Exception
-   {
-      queue.close();
-      super.tearDown();
-   }
-
-   public void crashChannel() throws Exception
-   {
-      queue.close();
-   }
-
-   public void recoverChannel() throws Exception
-   {
-      queue = new PagingFilteredQueue("queue1", 1, ms, pm, true, false, -1, null);
-   }
-
-   // Public --------------------------------------------------------
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}
-

Deleted: trunk/tests/src/org/jboss/test/messaging/core/local/RecoverablePagingFilteredQueueTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/RecoverablePagingFilteredQueueTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/RecoverablePagingFilteredQueueTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,84 +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.PagingFilteredQueue;
-import org.jboss.test.messaging.core.local.base.PagingFilteredQueueTestBase;
-
-/**
- * @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 RecoverablePagingFilteredQueueTest extends PagingFilteredQueueTestBase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-  
-   // Constructors --------------------------------------------------
-
-   public RecoverablePagingFilteredQueueTest(String name)
-   {
-      super(name);
-   }
-
-   // ChannelTestBase overrides  ------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-      
-      queue = new PagingFilteredQueue("queue1", 1, ms, pm, true, true, -1, null);
-   }
-
-   public void tearDown() throws Exception
-   {
-      queue.close();
-      super.tearDown();
-   }
-
-   public void crashChannel() throws Exception
-   {
-      queue.close();
-   }
-
-   public void recoverChannel() throws Exception
-   {
-      queue = new PagingFilteredQueue("queue1", 1, ms, pm, true, true, -1, null);
-   }
-
-   // Public --------------------------------------------------------
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/local/RoundRobinPointToPointRouterTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/RoundRobinPointToPointRouterTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/RoundRobinPointToPointRouterTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,562 +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.Delivery;
-import org.jboss.messaging.core.DeliveryObserver;
-import org.jboss.messaging.core.Receiver;
-import org.jboss.messaging.core.Router;
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.local.RoundRobinPointToPointRouter;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.message.SimpleMessageStore;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.test.messaging.util.CoreMessageFactory;
-
-/**
- * @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 $</tt>
- * $Id: $
- */
-public class RoundRobinPointToPointRouterTest extends MessagingTestCase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-   
-   protected MessageStore ms;
-
-   // Constructors --------------------------------------------------
-
-   public RoundRobinPointToPointRouterTest(String name)
-   {
-      super(name);
-   }
-
-   // ChannelTestBase overrides  ------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-      
-      ms = new SimpleMessageStore();
-      
-      ms.start();
-   }
-
-   public void tearDown() throws Exception
-   {
-      super.tearDown();
-      
-      ms.stop();
-   }
-
-   // Public --------------------------------------------------------
-   
-   public void testAllAccepting()
-   {
-      Router router = new RoundRobinPointToPointRouter();
-      
-      final int numReceivers = 10;
-      
-      SimpleReceiver[] receivers = new SimpleReceiver[numReceivers];
-      
-      for (int i = 0; i < numReceivers; i++)
-      {
-         receivers[i] = new SimpleReceiver();
-         
-         router.add(receivers[i]);
-      }
-      
-      Message msg = CoreMessageFactory.createCoreMessage(123, true, null);
-      
-      MessageReference ref = ms.reference(msg);
-            
-      Delivery del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 0);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 1);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 2);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 3);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 4);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 5);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 6);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 7);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 8);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 9);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 0);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 1);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 2);
-      resetReceivers(receivers);
-      
-   }
-   
-   public void testSomeClosed()
-   {
-      Router router = new RoundRobinPointToPointRouter();
-      
-      final int numReceivers = 10;
-      
-      SimpleReceiver[] receivers = new SimpleReceiver[numReceivers];
-      
-      for (int i = 0; i < numReceivers; i++)
-      {
-         receivers[i] = new SimpleReceiver();
-         
-         router.add(receivers[i]);
-      }
-      
-      receivers[2].closed = true;
-      
-      receivers[5].closed = true;
-      receivers[6].closed = true;
-      
-      receivers[9].closed = true;
-      
-      Message msg = CoreMessageFactory.createCoreMessage(123, true, null);
-      
-      MessageReference ref = ms.reference(msg);
-      
-      Delivery del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 0);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 1);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 3);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 4);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 7);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 8);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 0);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 1);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 3);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 4);
-      resetReceivers(receivers);
-      
-      
-   }
-   
-   public void testAllClosed()
-   {
-      Router router = new RoundRobinPointToPointRouter();
-      
-      final int numReceivers = 10;
-      
-      SimpleReceiver[] receivers = new SimpleReceiver[numReceivers];
-      
-      for (int i = 0; i < numReceivers; i++)
-      {
-         receivers[i] = new SimpleReceiver();
-         
-         receivers[i].closed = true;
-         
-         router.add(receivers[i]);
-      }
-      
-      
-      Message msg = CoreMessageFactory.createCoreMessage(123, true, null);
-      
-      MessageReference ref = ms.reference(msg);
-      
-      Delivery del = router.handle(null, ref, null);
-      assertNull(del);
-
-      del = router.handle(null, ref, null);
-      assertNull(del);
-      
-      del = router.handle(null, ref, null);
-      assertNull(del);
-
-      
-      
-   }
-   
-   public void testSomeNoSelectorMatch()
-   {
-      Router router = new RoundRobinPointToPointRouter();
-      
-      final int numReceivers = 10;
-      
-      SimpleReceiver[] receivers = new SimpleReceiver[numReceivers];
-      
-      for (int i = 0; i < numReceivers; i++)
-      {
-         receivers[i] = new SimpleReceiver();
-         
-         router.add(receivers[i]);
-      }
-      
-      receivers[2].selectorMatches = false;
-      
-      receivers[5].selectorMatches = false;
-      receivers[6].selectorMatches = false;
-      
-      receivers[9].selectorMatches = false;
-      
-      Message msg = CoreMessageFactory.createCoreMessage(123, true, null);
-      
-      MessageReference ref = ms.reference(msg);
-      
-      Delivery del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 0);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 1);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 3);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 4);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 7);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 8);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 0);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 1);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 3);
-      resetReceivers(receivers);
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      checkReceiverGotRef(receivers, 4);
-      resetReceivers(receivers);
-      
-   }
-   
-   public void testAllNoSelectorMatch()
-   {
-      Router router = new RoundRobinPointToPointRouter();
-      
-      final int numReceivers = 10;
-      
-      SimpleReceiver[] receivers = new SimpleReceiver[numReceivers];
-      
-      for (int i = 0; i < numReceivers; i++)
-      {
-         receivers[i] = new SimpleReceiver();
-         
-         receivers[i].selectorMatches = false;
-         
-         router.add(receivers[i]);
-      }
-      
-      
-      Message msg = CoreMessageFactory.createCoreMessage(123, true, null);
-      
-      MessageReference ref = ms.reference(msg);
-      
-      Delivery del = router.handle(null, ref, null);
-      assertNotNull(del);
-      assertFalse(del.isSelectorAccepted());
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      assertFalse(del.isSelectorAccepted());
-      
-      del = router.handle(null, ref, null);
-      assertNotNull(del);
-      assertFalse(del.isSelectorAccepted());
-           
-   }
-   
-   public void testNoReceivers()
-   {
-      Router router = new RoundRobinPointToPointRouter();
-
-      Message msg = CoreMessageFactory.createCoreMessage(123, true, null);
-      
-      MessageReference ref = ms.reference(msg);
-      
-      Delivery del = router.handle(null, ref, null);
-      assertNull(del);
-      
-      del = router.handle(null, ref, null);
-      assertNull(del);
-      
-      del = router.handle(null, ref, null);
-      assertNull(del);    
-   }
-
-
-   /**
-    * http://jira.jboss.org/jira/browse/JBMESSAGING-491
-    */
-   public void testDeadlock() throws Exception
-   {
-      final Router router = new RoundRobinPointToPointRouter();
-
-      LockingReceiver receiver = new LockingReceiver();
-      router.add(receiver);
-
-      final Thread t = new Thread(new Runnable()
-      {
-         public void run()
-         {
-            // sends the message to the router on a separate thread
-            
-            Message msg = CoreMessageFactory.createCoreMessage(123, true, null);
-            
-            MessageReference ref = ms.reference(msg);
-            
-            router.handle(null, ref, null);
-         }
-      }, "Message sending thread");
-
-      // start the sending tread, which will immediately grab the router's "receivers" lock, and it
-      // will sleep for 3 seconds before attempting to grab LockingReceiver's lock.
-      t.start();
-
-
-      // in the mean time, the main thread immediately grabs receiver's lock ...
-
-      synchronized(receiver.getLock())
-      {
-         // ... sleeps for 500 ms to allow sender thread time to grab router's "receivers" lock
-         Thread.sleep(500);
-
-         // ... and try to remove the receiver form router
-         router.remove(receiver);
-      }
-
-      // normally, receiver removal should be immediate, as the router releases receiver's lock
-      // immediately, so test should complete. Pre-JBMESSAGING-491, the test deadlocks.
-   }
-   
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-
-   protected void checkReceiverGotRef(SimpleReceiver[] receivers, int pos)
-   {
-      for (int i = 0; i < receivers.length; i++)
-      {
-         SimpleReceiver r = receivers[i];
-
-         if (i == pos)
-         {
-            assertTrue(r.gotRef);
-         }
-         else
-         {
-            assertFalse(r.gotRef);
-         }
-      }
-   }
-
-   protected void resetReceivers(SimpleReceiver[] receivers)
-   {
-      for (int i = 0; i < receivers.length; i++)
-      {
-         SimpleReceiver r = receivers[i];
-
-         r.gotRef = false;
-      }
-   }
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------  
-   
-   class LockingReceiver implements Receiver
-   {
-      private Object lock;
-
-      public LockingReceiver()
-      {
-         lock = new Object();
-      }
-
-      public Delivery handle(DeliveryObserver observer, MessageReference ref, Transaction tx)
-      {
-         // The delivering thread needs to grab the receiver's lock to complete delivery; this
-         // is how Messaging receivers are written, anyway. We simulate the race condition by
-         // putting the sending thread to sleep for 3 seconds before allowing it to attempt to
-         // grab the lock
-
-         try
-         {
-            Thread.sleep(3000);
-         }
-         catch(InterruptedException e)
-         {
-            // this shouldn't happen in the test
-            return null;
-         }
-
-         synchronized(lock)
-         {
-            return new SimpleDelivery(null, null, true, true);
-         }
-      }
-
-      public Object getLock()
-      {
-         return lock;
-      }
-   }
-   
-   class SimpleReceiver implements Receiver
-   {
-      boolean selectorMatches = true;
-      
-      boolean closed;
-      
-      boolean gotRef;
-
-      public Delivery handle(DeliveryObserver observer, MessageReference ref, Transaction tx)
-      {
-         if (closed)
-         {
-            return null;
-         }
-         
-         Delivery del = new SimpleDelivery(null, null, true, selectorMatches);
-         
-         if (selectorMatches)
-         {
-            gotRef = true;
-         }
-                  
-         return del;
-      }
-      
-   }
-
-
-   
-
-}
-

Deleted: trunk/tests/src/org/jboss/test/messaging/core/local/base/PagingFilteredQueueTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/base/PagingFilteredQueueTestBase.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/base/PagingFilteredQueueTestBase.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,6451 +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.io.Serializable;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.Filter;
-import org.jboss.messaging.core.Receiver;
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.CoreMessage;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.message.SimpleMessageStore;
-import org.jboss.messaging.core.plugin.IDManager;
-import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
-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.SimpleFilter;
-import org.jboss.test.messaging.core.SimpleReceiver;
-import org.jboss.test.messaging.tools.jmx.ServiceContainer;
-import org.jboss.test.messaging.util.CoreMessageFactory;
-
-/**
- * The QueueTest test strategy is to try as many combination as it makes sense of the following
- * variables:
- *
- * 1. The Queue can be non-recoverable  or
- *    recoverable. A non-recoverable channel can accept reliable messages or not.
- * 2. The Queue 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 PagingFilteredQueueTestBase 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 PagingFilteredQueue queue;
-   
-   protected IDManager idm;
-   
-   // Constructors --------------------------------------------------
-
-   public PagingFilteredQueueTestBase(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-      
-      sc = new ServiceContainer("all,-remoting,-security");
-      sc.start();
-
-      pm = new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager(),
-                                      sc.getPersistenceManagerSQLProperties(),
-                                      true, true, true, false, 100);
-      pm.start();
-      
-      idm = new IDManager("TRANSACTION_ID", 10, pm);
-      idm.start();
-      
-      ms = new SimpleMessageStore();
-      ms.start();
-      
-      tr = new TransactionRepository(pm, ms, idm);
-      tr.start();
-      
-   }
-
-   public void tearDown() throws Exception
-   {
-      sc.stop();
-      
-      pm.stop();
-      idm.stop();
-      tr.stop();
-      ms.stop();
-      
-      sc = null;   
-      pm = null;
-      idm = null;
-      ms = null;
-      tr = null;
-      super.tearDown();
-   }
-
-   public static void assertEqualSets(MessageReference[] a, List msgs)
-   {
-      assertEquals(a.length, msgs.size());
-      List l = new ArrayList(msgs);
-
-      for(int i = 0; i < a.length; i++)
-      {
-         for(Iterator j = l.iterator(); j.hasNext(); )
-         {
-            Object o = j.next();
-            Message m = (Message)o;
-            
-            if (a[i].getMessage().getMessageID() == m.getMessageID() &&
-                m.getPayload().equals(a[i].getMessage().getPayload()))
-            {
-               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().getMessage().getMessageID() == ref.getMessage().getMessageID())
-            {
-               j.remove();
-               break;
-            }
-         }
-      }
-
-      if (!l.isEmpty())
-      {
-         fail("Deliveries " + l + " do not match!");
-      }
-   }
-
-
-   // Channel tests -------------------------------------------------
-   
-
-   public void testWithFilter()
-   {
-      Filter f = new SimpleFilter(3);
-            
-      PagingFilteredQueue queue = new PagingFilteredQueue("queue1", 1, ms, pm, true, false, -1, f);
-      
-      Message m1 = new CoreMessage(1, false, 0, 0, (byte)0, null, null);
-      Message m2 = new CoreMessage(2, false, 0, 0, (byte)0, null, null);
-      Message m3 = new CoreMessage(3, false, 0, 0, (byte)0, null, null);
-      Message m4 = new CoreMessage(4, false, 0, 0, (byte)0, null, null);
-      Message m5 = new CoreMessage(5, false, 0, 0, (byte)0, null, null);
-      
-      MessageReference ref1 = ms.reference(m1);
-      MessageReference ref2 = ms.reference(m2);
-      MessageReference ref3 = ms.reference(m3);
-      MessageReference ref4 = ms.reference(m4);
-      MessageReference ref5 = ms.reference(m5);
-      
-      Delivery del = queue.handle(null, ref1, null);
-      assertFalse(del.isSelectorAccepted());
-      
-      del = queue.handle(null, ref2, null);
-      assertFalse(del.isSelectorAccepted());
-      
-      del = queue.handle(null, ref3, null);
-      assertTrue(del.isSelectorAccepted());
-      
-      del = queue.handle(null, ref4, null);
-      assertFalse(del.isSelectorAccepted());
-      
-      del = queue.handle(null, ref5, null);
-      assertFalse(del.isSelectorAccepted());
-   }
-   
-   
-   public void testUnreliableSynchronousDeliveryTwoReceivers() throws Exception
-   {
-      if (queue.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);
-      
-      queue.add(r1);
-      queue.add(r2);
-      
-      Delivery d = queue.handle(observer, createReference(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 (!queue.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(queue.add(r1));
-      assertTrue(queue.add(r2));
-
-      Delivery d = queue.handle(observer, createReference(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(queue.iterator().hasNext());
-      
-      queue.add(receiver1);
-      
-      assertTrue(queue.contains(receiver1));
-      
-      queue.remove(receiver1);
-      
-      assertFalse(queue.iterator().hasNext());
-      
-      assertFalse(queue.contains(receiver1));
-      
-      queue.add(receiver1);
-      
-      assertTrue(queue.contains(receiver1));
-      
-      queue.remove(receiver2);
-      
-      assertTrue(queue.contains(receiver1));
-                 
-   }
-
-   public void testClosedChannel() throws Exception
-   {
-      queue.close();
-      try
-      {
-         queue.handle(null, createReference(0), null);
-         fail("should throw exception");
-      }
-      catch(IllegalStateException e)
-      {
-         //OK
-      }
-   }
-
-   public void testHandleNullRoutable() throws Exception
-   {
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-      assertNull(queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      List stored = queue.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);
-      queue.add(receiver);
-      queue.deliver();
-      assertEquals(1, receiver.getMessages().size());
-      assertEquals(0, ((Message)receiver.getMessages().get(0)).getMessageID());
-
-      queue.deliver();
-      assertEquals(1, receiver.getMessages().size());
-
-
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_2() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      List stored = queue.browse();
-      assertEqualSets(refs, stored);
-
-      SimpleReceiver receiver = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
-      queue.add(receiver);
-      queue.deliver();
-      assertEquals(10, receiver.getMessages().size());
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         assertEquals(i, ((Message)receiver.getMessages().get(i)).getMessageID());         
-      }
-      receiver.clear();
-
-      queue.deliver();
-      assertEquals(0, receiver.getMessages().size());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_3_1() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      // the channel must not accept the message
-      assertNull(delivery);
-
-      assertTrue(queue.browse().isEmpty());
-
-      queue.deliver();
-      
-      Receiver r = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
-      
-      queue.add(r);
-      
-      queue.deliver();
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_3_2() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-      
-      log.trace("ref is reliable:" + ref.getMessage().isReliable());
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      List stored = queue.browse();
-      assertEquals(1, stored.size());
-
-      Message sm = (Message)stored.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-
-      queue.deliver();
-
-      SimpleReceiver receiver = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
-      queue.add(receiver);
-      queue.deliver();
-      assertEquals(1, receiver.getMessages().size());
-      assertEquals(0, ((Message)receiver.getMessages().get(0)).getMessageID());
-
-      queue.deliver();
-      assertEquals(1, receiver.getMessages().size());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_4_1() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         // the channel must not accept the message
-         assertNull(delivery);
-
-         queue.deliver();
-         
-         Receiver r = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
-         
-         queue.add(r);
-         
-         queue.deliver();
-      }
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_4_2() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(refs, queue.browse());
-
-      SimpleReceiver receiver = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
-      queue.add(receiver);
-      queue.deliver();
-      assertEquals(10, receiver.getMessages().size());
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         assertEquals(i, ((Message)receiver.getMessages().get(i)).getMessageID());         
-      }
-      receiver.clear();
-
-      queue.deliver();
-      assertEquals(0, receiver.getMessages().size());
-   }
-
-
-
-   //////
-   ////// Transacted send and commit
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_5() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.commit();
-
-      List stored = queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.commit();
-
-      List stored = queue.browse();
-      assertEqualSets(refs, stored);
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_7_1() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      try
-      {
-         tx.commit();
-         fail("this should throw exception");
-      }
-      catch(Exception e)
-      {
-         // OK
-      }
-
-      // still no messages in the channel
-      assertEquals(0, queue.browse().size());
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_7_2() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.commit();
-
-      List stored = queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      try
-      {
-         tx.commit();
-         fail("this should throw exception");
-      }
-      catch(Exception e)
-      {
-         // OK
-      }
-
-      // still no messages in the channel
-      assertEquals(0, queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      try
-      {
-         tx.commit();
-         fail("this should throw exception");
-      }
-      catch(Exception e)
-      {
-         // OK
-      }
-
-      // still no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-   }
-   
-   public void testNonRecoverableChannel_8_1_mixed_1() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES * 2];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i + NUMBER_OF_MESSAGES] = createReference(i + NUMBER_OF_MESSAGES , true, "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i + NUMBER_OF_MESSAGES], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      try
-      {
-         tx.commit();
-         fail("this should throw exception");
-      }
-      catch(Exception e)
-      {
-         // OK
-      }
-
-      // still no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-   }
-   
-
-   public void testNonRecoverableChannel_8_1_mixed_2() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES * 2];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i + NUMBER_OF_MESSAGES] = createReference(i + NUMBER_OF_MESSAGES , true, "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i + NUMBER_OF_MESSAGES], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      try
-      {
-         tx.commit();
-         fail("this should throw exception");
-      }
-      catch(Exception e)
-      {
-         // OK
-      }
-
-      // still no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_8_2() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.commit();
-
-      assertEqualSets(refs, queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.commit();
-
-      assertEqualSets(refs, queue.browse());
-   }
-
-
-   //////
-   ////// Transacted send and rollback
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_9() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, queue.browse().size());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_10() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, queue.browse().size());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_11() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, queue.browse().size());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_12() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, queue.browse().size());
-   }
-
-   ////
-   //// One receiver
-   ////
-
-   //////
-   ////// ACKING receiver
-   //////
-
-   //////
-   ////// Non-transacted send
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_13() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-      assertTrue(queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertTrue(queue.browse().isEmpty());
-
-      List received = r.getMessages();
-      assertEqualSets(refs, received);
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_15_1() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.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(queue.add(r));
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertNull(delivery);
-
-      assertTrue(queue.browse().isEmpty());
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_15_2() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      assertTrue(queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.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(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertNull(delivery);
-      }
-
-      assertTrue(queue.browse().isEmpty());
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_16_2() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertTrue(queue.browse().isEmpty());
-      assertEqualSets(refs, r.getMessages());
-   }
-
-   //////
-   ////// Transacted send and commit
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_17() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      assertTrue(queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      assertTrue(queue.browse().isEmpty());
-      assertEqualSets(refs, r.getMessages());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_19_1() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.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(queue.add(r));
-
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, queue.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, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_19_2() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      // no messages in the channel
-      assertEquals(0, queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.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(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.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, queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.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(queue.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.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, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_20_2() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      assertEqualSets(refs, 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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      assertEqualSets(refs, r.getMessages());
-   }
-
-   //////
-   ////// Transacted send and rollback
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_21() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_22() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_23() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_24() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-   
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      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(queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      r.setImmediateAsynchronousAcknowledgment(true);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      // the receiver should have returned a "done" delivery
-      assertTrue(queue.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(queue.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment and commit
-   ////////////
-
-   public void testNonRecoverableChannel_25_1() throws Throwable
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      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);
-
-      deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      tx.commit();
-
-      assertTrue(queue.browse().isEmpty());
-      
-      deliveringCount = queue.getDeliveringCount();
-      assertEquals(0, deliveringCount);
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment and rollback
-   ////////////
-
-   public void testNonRecoverableChannel_25_2() throws Throwable
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      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);
-
-      deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      tx.rollback();
-
-      deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      // acknowledge non-transactionally
-      r.acknowledge(ackm, null);
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   ////////////
-   //////////// Non-transacted acknowledgment
-   ////////////
-
-   public void testNonRecoverableChannel_26() throws Throwable
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(refs, r.getMessages());
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(queue.browse().isEmpty());
-
-   }
-
-   ////////////
-   //////////// Transacted acknowledgment and commit
-   ////////////
-
-   public void testNonRecoverableChannel_26_1() throws Throwable
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(refs, 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);
-      }
-
-      tx.commit();
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment and rollback
-   ////////////
-
-   public void testNonRecoverableChannel_26_2() throws Throwable
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(refs, 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);
-      }
-
-      tx.rollback();
-
-      // acknowledge non-transactionally
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   ////////////
-   //////////// Non-transacted acknowledgment
-   ////////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_27_1_1() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      // not accepted by the channel
-      assertNull(delivery);
-      assertTrue(queue.browse().isEmpty());
-      assertTrue(r.getMessages().isEmpty());
-
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_27_1_2() throws Throwable
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      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(queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      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);
-
-      deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      tx.commit();
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   ////////////
-   //////////// Non-transacted acknowledgment
-   ////////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_28_1_1() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         // not accepted by the channel
-         assertNull(delivery);
-      }
-
-      assertTrue(queue.browse().isEmpty());
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_28_1_2() throws Throwable
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(refs, r.getMessages());
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(refs, r.getMessages());
-
-      Transaction tx = tr.createTransaction();
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         r.acknowledge(ackm, tx);
-      }
-
-      tx.commit();
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-   //////
-   ////// Transacted send and commit
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_29() throws Throwable
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      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(queue.browse().isEmpty());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_30() throws Throwable
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      assertEqualSets(refs, r.getMessages());
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_31_1() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, queue.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, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ///////////
-   /////////// Channel does accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_31_2() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);      
-
-      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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.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, queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (queue.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.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, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_32_2() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(NUMBER_OF_MESSAGES, deliveringCount);
-      
-      assertEqualSets(refs, 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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!queue.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(NUMBER_OF_MESSAGES, deliveringCount);
-      assertEqualSets(refs, r.getMessages());
-   }
-
-
-
-   //////
-   ////// Transacted send and rollback
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_33() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_34() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_35() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_36() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-
-
-
-   //
-   // Recoverable channel
-   //
-
-   public void testRecoverableChannel_0() throws Exception
-   {
-      if (queue.isRecoverable())
-      {
-         assertTrue(queue.acceptReliableMessages());
-      }
-   }
-
-   ////
-   //// Zero receivers
-   ////
-
-   //////
-   ////// Non-transacted send
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_1() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      List stored = queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(refs, queue.browse());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_3() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      List stored = queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(refs, queue.browse());
-
-   }
-
-   //////
-   ////// Transacted send and commit
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_5() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.commit();
-
-      List stored = queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.commit();
-
-      assertEqualSets(refs, queue.browse());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_7() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.commit();
-
-      List stored = queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.commit();
-
-      assertEqualSets(refs, queue.browse());
-   }
-
-   /**
-    * This is a variation where I send a mixture of reliable and non-reliable messages,
-    */
-   public void testRecoverableChannel_8_mixed() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.commit();
-
-      assertEqualSets(refs, queue.browse());
-   }
-
-
-   //////
-   ////// Transacted send and rollback
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_9() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, queue.browse().size());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_10() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, queue.browse().size());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_11() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, queue.browse().size());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_12() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, queue.browse().size());
-   }
-
-   ////
-   //// One receiver
-   ////
-
-   //////
-   ////// ACKING receiver
-   //////
-
-   //////
-   ////// Non-transacted send
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_13() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-      assertTrue(queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertTrue(queue.browse().isEmpty());
-
-      List received = r.getMessages();
-      assertEqualSets(refs, received);
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_15() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      assertTrue(queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertTrue(queue.browse().isEmpty());
-      assertEqualSets(refs, r.getMessages());
-   }
-
-   //////
-   ////// Transacted send and commit
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_17() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      assertTrue(queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      BrokenReceiver brokenReceiver = new BrokenReceiver(2);
-      assertTrue(queue.add(brokenReceiver));
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      ref = createReference(1, false, "payload");
-
-      log.debug("sending message 2");
-      queue.handle(observer, ref, tx);
-
-      ref = createReference(2, false, "payload");
-
-      log.debug("sending message 3");
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      tx.commit();
-
-      assertEquals(2, queue.browse().size());
-      assertEquals(1, brokenReceiver.getMessages().size());
-   }
-
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_18() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      assertTrue(queue.browse().isEmpty());
-      assertEqualSets(refs, r.getMessages());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_19() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      // no messages in the channel
-      assertEquals(0, queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      assertEqualSets(refs, 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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      assertEqualSets(refs, r.getMessages());
-   }
-
-
-   //////
-   ////// Transacted send and rollback
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_21() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_22() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_23() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_24() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(queue.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      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(queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      r.setImmediateAsynchronousAcknowledgment(true);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      // the receiver should have returned a "done" delivery
-      assertTrue(queue.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(queue.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment and commit
-   ////////////
-
-   public void testRecoverableChannel_25_1() throws Throwable
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      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);
-
-      deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      tx.commit();
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment and rollback
-   ////////////
-
-   public void testRecoverableChannel_25_2() throws Throwable
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      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);
-
-      deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      tx.rollback();
-
-      deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      // acknowledge non-transactionally
-      r.acknowledge(ackm, null);
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   ////////////
-   //////////// Non-transacted acknowledgment
-   ////////////
-
-   public void testRecoverableChannel_26() throws Throwable
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
-      assertEqualSets(refs, r.getMessages());
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(queue.browse().isEmpty());
-
-   }
-
-   ////////////
-   //////////// Transacted acknowledgment and commit
-   ////////////
-
-   public void testRecoverableChannel_26_1() throws Throwable
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
-      assertEqualSets(refs, 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);
-      }
-
-      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
-
-      tx.commit();
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment and rollback
-   ////////////
-
-   public void testRecoverableChannel_26_2() throws Throwable
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
-      assertEqualSets(refs, 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);
-      }
-
-      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
-
-      tx.rollback();
-
-      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
-
-      // acknowledge non-transactionally
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   ////////////
-   //////////// Non-transacted acknowledgment
-   ////////////
-
-   public void testRecoverableChannel_27() throws Throwable
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      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(queue.browse().isEmpty());
-   }
-
-   /**
-    * Test duplicate acknowledgment.
-    */
-   public void testRecoverableChannel_27_Duplicate_ACK() throws Throwable
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      queue.handle(observer, ref, null);
-
-      Message ackm = (Message)r.getMessages().get(0);
-
-      // acknowledge once
-      r.acknowledge(ackm, null);
-
-      assertTrue(queue.browse().isEmpty());
-
-      // acknowledge twice
-      try
-      {
-         r.acknowledge(ackm, null);
-      }
-      catch(IllegalStateException e)
-      {
-         // OK
-      }
-
-      assertTrue(queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      r.setImmediateAsynchronousAcknowledgment(true);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      // the receiver should have returned a "done" delivery
-      assertTrue(queue.browse().isEmpty());
-
-      List messages = r.getMessages();
-      assertEquals(1, messages.size());
-      Message ackm = (Message)messages.get(0);
-      assertEquals(0, ackm.getMessageID());
-
-      // Acknowledgment handling implemenation is NOT idempotent, the channel DOES NOT allow
-      // extraneous duplicate acknowlegments, so we test for that.
-
-      try
-      {
-         r.acknowledge(ackm, null);
-      }
-      catch(IllegalStateException e)
-      {
-         // OK
-         log.trace(e);
-
-      }
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment and commit
-   ////////////
-
-   public void testRecoverableChannel_27_1() throws Throwable
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      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);
-
-      deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      tx.commit();
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment and rollback
-   ////////////
-
-   public void testRecoverableChannel_27_2() throws Throwable
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = queue.handle(observer, ref, null);
-
-      assertTrue(delivery.isDone());
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      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);
-
-      deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      tx.rollback();
-
-      deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      // acknowledge non-transactionally
-      r.acknowledge(ackm, null);
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   ////////////
-   //////////// Non-transacted acknowledgment
-   ////////////
-
-   public void testRecoverableChannel_28() throws Throwable
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
-      
-      assertEqualSets(refs, r.getMessages());
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-   ////////////
-   //////////// Transacted acknowledgment and commit
-   ////////////
-
-   public void testRecoverableChannel_28_1() throws Throwable
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
-      assertEqualSets(refs, 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);
-      }
-
-      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
-
-      tx.commit();
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-   ////////////
-   //////////// Transacted acknowledgment and rollback
-   ////////////
-
-   public void testRecoverableChannel_28_2() throws Throwable
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = queue.handle(observer, refs[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
-      assertEqualSets(refs, 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);
-      }
-
-      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
-
-      tx.rollback();
-
-      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
-
-      // acknowledge non-transactionally
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-
-   //////
-   ////// Transacted send and commit
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_29() throws Throwable
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      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(queue.browse().isEmpty());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_30() throws Throwable
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
-      assertEqualSets(refs, r.getMessages());
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_31() throws Throwable
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      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(queue.browse().isEmpty());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_32() throws Throwable
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-      
-      
-      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
-      assertEqualSets(refs, r.getMessages());
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-      
-      assertEquals(NUMBER_OF_MESSAGES, queue.getDeliveringCount());
-      assertEqualSets(refs, r.getMessages());
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(queue.browse().isEmpty());
-   }
-
-
-   //////
-   ////// Transacted send and rollback
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_33() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_34() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_35() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-
-      MessageReference ref = createReference(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
-      queue.handle(observer, ref, tx);
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_36() throws Exception
-   {
-      if (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         refs[i] = createReference(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.ACCEPTING);
-      assertTrue(queue.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         refs[i] = createReference(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         queue.handle(observer, refs[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, queue.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-recoverable channel, non-reliable message
-      Delivery delivery = queue.handle(observer, ref, null);
-      assertTrue(delivery.isDone());
-
-      List stored = queue.browse();
-      assertEquals(1, stored.size());
-
-
-      SimpleReceiver receiver = new SimpleReceiver("BrokenReceiver", SimpleReceiver.BROKEN);
-      assertTrue(queue.add(receiver));
-
-      stored = queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-recoverable channel, non-reliable message
-      Delivery delivery = queue.handle(observer, ref, null);
-      assertTrue(delivery.isDone());
-
-      List stored = queue.browse();
-      assertEquals(1, stored.size());
-
-      SimpleReceiver receiver =
-            new SimpleReceiver("ACKINGReceiver", SimpleReceiver.ACKING, queue);
-      assertTrue(queue.add(receiver));
-
-      assertEquals(1, queue.browse().size());
-
-      // receiver explicitely asks for message
-      receiver.requestMessages();
-
-      assertTrue(queue.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 (queue.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-recoverable channel, non-reliable message
-      Delivery delivery = queue.handle(observer, ref, null);
-      assertTrue(delivery.isDone());
-
-      List stored = queue.browse();
-      assertEquals(1, stored.size());
-
-      SimpleReceiver receiver =
-            new SimpleReceiver("NACKINGReceiver", SimpleReceiver.ACCEPTING, queue);
-      assertTrue(queue.add(receiver));
-
-      assertEquals(1, queue.browse().size());
-
-      // receiver explicitely asks for message
-      receiver.requestMessages();
-
-      int deliveringCount = queue.getDeliveringCount();
-      assertEquals(1, deliveringCount);
-
-      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(queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-recoverable channel, non-reliable message
-      Delivery delivery = queue.handle(observer, ref, null);
-      assertTrue(delivery.isDone());
-
-      List stored = queue.browse();
-      assertEquals(1, stored.size());
-
-
-      SimpleReceiver receiver = new SimpleReceiver("BrokenReceiver", SimpleReceiver.BROKEN);
-      assertTrue(queue.add(receiver));
-
-      stored = queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-recoverable channel, non-reliable message
-      Delivery delivery = queue.handle(observer, ref, null);
-      assertTrue(delivery.isDone());
-
-      List stored = queue.browse();
-      assertEquals(1, stored.size());
-
-      SimpleReceiver receiver =
-            new SimpleReceiver("ACKINGReceiver", SimpleReceiver.ACKING, queue);
-      assertTrue(queue.add(receiver));
-
-      // receiver explicitely asks for message
-      receiver.requestMessages();
-
-      assertTrue(queue.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 (!queue.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(queue.iterator().hasNext());
-
-      MessageReference ref = createReference(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-recoverable channel, non-reliable message
-      Delivery delivery = queue.handle(observer, ref, null);
-      assertTrue(delivery.isDone());
-
-      List stored = queue.browse();
-      assertEquals(1, stored.size());
-
-      SimpleReceiver receiver =
-            new SimpleReceiver("NACKINGReceiver", SimpleReceiver.ACCEPTING, queue);
-      assertTrue(queue.add(receiver));
-
-      assertEquals(1, queue.browse().size());
-
-      // receiver explicitely asks for message
-      receiver.requestMessages();
-
-      assertEquals(1, queue.getDeliveringCount());
-
-      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(queue.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, ref, 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(queue.add(r));
-      assertFalse(queue.add(r));
-
-      assertTrue(queue.contains(r));
-
-      Iterator i = queue.iterator();
-      assertEquals(r, i.next());
-      assertFalse(i.hasNext());
-
-      queue.clear();
-      assertFalse(queue.iterator().hasNext());
-   }
-
-   public void testRemoveInexistentReceiver()
-   {
-      assertFalse(queue.remove(new SimpleReceiver("INEXISTENT")));
-   }
-
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-
-   protected abstract void crashChannel() throws Exception;
-
-   protected abstract void recoverChannel() throws Exception;
-
-   // Private -------------------------------------------------------
-   
-   private MessageReference createReference(long id, boolean reliable, Serializable payload)
-   {
-      return ms.reference(CoreMessageFactory.createCoreMessage(id, reliable, payload));
-   }
-   
-   private MessageReference createReference(long id)
-   {
-      return ms.reference(CoreMessageFactory.createCoreMessage(id));
-   }
-   
-   // Inner classes -------------------------------------------------
-
-}

Modified: trunk/tests/src/org/jboss/test/messaging/core/message/CoreMessageTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/message/CoreMessageTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/message/CoreMessageTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -21,7 +21,6 @@
 */
 package org.jboss.test.messaging.core.message;
 
-import org.jboss.test.messaging.core.message.base.RoutableSupportTestBase;
 import org.jboss.test.messaging.util.CoreMessageFactory;
 
 
@@ -31,7 +30,7 @@
  *
  * $Id$
  */
-public class CoreMessageTest extends RoutableSupportTestBase
+public class CoreMessageTest extends MessageSupportTestBase
 {
    // Constants -----------------------------------------------------
 

Modified: trunk/tests/src/org/jboss/test/messaging/core/message/JBossMessageTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/message/JBossMessageTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/message/JBossMessageTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -22,9 +22,8 @@
 package org.jboss.test.messaging.core.message;
 
 import org.jboss.jms.message.JBossMessage;
-import org.jboss.messaging.core.message.MessageFactory;
-import org.jboss.messaging.core.message.MessageSupport;
-import org.jboss.test.messaging.core.message.base.RoutableSupportTestBase;
+import org.jboss.messaging.core.impl.message.MessageFactory;
+import org.jboss.messaging.core.impl.message.MessageSupport;
 
 
 /**
@@ -33,7 +32,7 @@
  *
  * $Id$
  */
-public class JBossMessageTest extends RoutableSupportTestBase
+public class JBossMessageTest extends MessageSupportTestBase
 {
    // Constants -----------------------------------------------------
 

Added: trunk/tests/src/org/jboss/test/messaging/core/message/MessageSupportTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/message/MessageSupportTestBase.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/message/MessageSupportTestBase.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,80 @@
+/*
+* 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.message;
+
+import org.jboss.messaging.core.impl.message.MessageSupport;
+import org.jboss.test.messaging.MessagingTestCase;
+
+
+/**
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @version <tt>$Revision: 2202 $</tt>
+ *
+ * $Id: RoutableSupportTestBase.java 2202 2007-02-08 10:50:26Z timfox $
+ */
+public class MessageSupportTestBase extends MessagingTestCase
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+
+   // Attributes ----------------------------------------------------
+
+   protected MessageSupport ms;
+
+   // Constructors --------------------------------------------------
+
+   public MessageSupportTestBase(String name)
+   {
+      super(name);
+   }
+
+   // Public --------------------------------------------------------
+
+   public void testNullAsHeaderValue() throws Exception
+   {
+      ms.putHeader("someHeader", null);
+      assertTrue(ms.containsHeader("someHeader"));
+      assertNull(ms.getHeader("someHeader"));
+      assertNull(ms.removeHeader("someHeader"));
+      assertFalse(ms.containsHeader("someHeader"));
+   }
+
+   // Package protected ---------------------------------------------
+
+   // Protected -----------------------------------------------------
+
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+   }
+
+   protected void tearDown() throws Exception
+   {
+      super.tearDown();
+   }
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+
+}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/message/base/RoutableSupportTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/message/base/RoutableSupportTestBase.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/message/base/RoutableSupportTestBase.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,80 +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.message.base;
-
-import org.jboss.messaging.core.message.MessageSupport;
-import org.jboss.test.messaging.MessagingTestCase;
-
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class RoutableSupportTestBase extends MessagingTestCase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-
-   // Attributes ----------------------------------------------------
-
-   protected MessageSupport ms;
-
-   // Constructors --------------------------------------------------
-
-   public RoutableSupportTestBase(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-
-   public void testNullAsHeaderValue() throws Exception
-   {
-      ms.putHeader("someHeader", null);
-      assertTrue(ms.containsHeader("someHeader"));
-      assertNull(ms.getHeader("someHeader"));
-      assertNull(ms.removeHeader("someHeader"));
-      assertFalse(ms.containsHeader("someHeader"));
-   }
-
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-
-   protected void setUp() throws Exception
-   {
-      super.setUp();
-   }
-
-   protected void tearDown() throws Exception
-   {
-      super.tearDown();
-   }
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-
-}

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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_2PCTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,12 +23,11 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.LockMap;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.test.messaging.core.paging.base.PagingStateTestBase;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.util.LockMap;
 import org.jboss.test.messaging.util.CoreMessageFactory;
 
 
@@ -62,10 +61,10 @@
    }
    
    public void testChannelShareNP_2PC() throws Throwable
-   {
-      PagingFilteredQueue queue1 = new PagingFilteredQueue("queue1", 1, ms, pm, true, true, -1, null, 100, 20, 10);
+   {   	   	
+      MessagingQueue queue1 = new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, 100, 20, 10, false, false);
       
-      PagingFilteredQueue queue2 = new PagingFilteredQueue("queue2", 2, ms, pm, true, true, -1, null, 50, 10, 5);
+      MessagingQueue queue2 = new MessagingQueue(1, "queue2", 2, ms, pm, true, -1, null, 50, 10, 5, false, false);
      
       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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_NTTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,11 +23,10 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.LockMap;
-import org.jboss.test.messaging.core.paging.base.PagingStateTestBase;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.util.LockMap;
 import org.jboss.test.messaging.util.CoreMessageFactory;
 
 
@@ -62,10 +61,10 @@
    
    public void test1() throws Throwable
    {
-      PagingFilteredQueue queue1 = new PagingFilteredQueue("queue1", 1, ms, pm, true, true, -1, null, 100, 20, 10);
+      MessagingQueue queue1 = new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, 100, 20, 10, false, false);
+      
+      MessagingQueue queue2 = new MessagingQueue(1, "queue2", 2, ms, pm, true, -1, null, 50, 10, 5, false, false);
      
-      PagingFilteredQueue queue2 = new PagingFilteredQueue("queue2", 2, ms, pm, true, true, -1, null, 50, 10, 5);
-           
       Message[] msgs = new Message[150];
       
       MessageReference[] refs1 = new MessageReference[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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_TTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,12 +23,11 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.LockMap;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.test.messaging.core.paging.base.PagingStateTestBase;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.util.LockMap;
 import org.jboss.test.messaging.util.CoreMessageFactory;
 
 
@@ -63,11 +62,10 @@
    
    public void testChannelShareNP_Transactional() throws Throwable
    {
-      PagingFilteredQueue queue1 = new PagingFilteredQueue("queue1", 1, ms, pm, true, true, -1, null, 100, 20, 10);
+      MessagingQueue queue1 = new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, 100, 20, 10, false, false);
       
-      PagingFilteredQueue queue2 = new PagingFilteredQueue("queue2", 2, ms, pm, true, true, -1, null, 50, 10, 5);
-     
-                               
+      MessagingQueue queue2 = new MessagingQueue(1, "queue2", 2, ms, pm, true, -1, null, 50, 10, 5, false, false);
+                             
       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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_2PCTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,12 +23,11 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.LockMap;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.test.messaging.core.paging.base.PagingStateTestBase;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.util.LockMap;
 import org.jboss.test.messaging.util.CoreMessageFactory;
 
 
@@ -58,11 +57,10 @@
    
    public void test1() throws Throwable
    {
-      PagingFilteredQueue queue1 = new PagingFilteredQueue("queue1", 1, ms, pm, true, true, -1, null, 100, 20, 10);
+      MessagingQueue queue1 = new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, 100, 20, 10, false, false);
       
-      PagingFilteredQueue queue2 = new PagingFilteredQueue("queue2", 2, ms, pm, true, true, -1, null, 50, 10, 5);
-     
-                            
+      MessagingQueue queue2 = new MessagingQueue(1, "queue2", 2, ms, pm, true, -1, null, 50, 10, 5, false, false);
+                        
       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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_NTTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,11 +23,10 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.LockMap;
-import org.jboss.test.messaging.core.paging.base.PagingStateTestBase;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.util.LockMap;
 import org.jboss.test.messaging.util.CoreMessageFactory;
 
 /**
@@ -62,11 +61,10 @@
    
    public void test1() throws Throwable
    {
-      PagingFilteredQueue queue1 = new PagingFilteredQueue("queue1", 1, ms, pm, true, true, -1, null, 100, 20, 10);
+      MessagingQueue queue1 = new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, 100, 20, 10, false, false);
       
-      PagingFilteredQueue queue2 = new PagingFilteredQueue("queue2", 2, ms, pm, true, true, -1, null, 50, 10, 5);
-     
-                                
+      MessagingQueue queue2 = new MessagingQueue(1, "queue2", 2, ms, pm, true, -1, null, 50, 10, 5, false, false);
+                
       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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_TTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,12 +23,11 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.LockMap;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.test.messaging.core.paging.base.PagingStateTestBase;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.util.LockMap;
 import org.jboss.test.messaging.util.CoreMessageFactory;
 
 /**
@@ -62,10 +61,10 @@
    
    public void test1() throws Throwable
    {
-      PagingFilteredQueue queue1 = new PagingFilteredQueue("queue1", 1, ms, pm, true, true, -1, null, 100, 20, 10);
+      MessagingQueue queue1 = new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, 100, 20, 10, false, false);
       
-      PagingFilteredQueue queue2 = new PagingFilteredQueue("queue2", 2, ms, pm, true, true, -1, null, 50, 10, 5);
-                                
+      MessagingQueue queue2 = new MessagingQueue(1, "queue2", 2, ms, pm, true, -1, null, 50, 10, 5, false, false);
+                       
       Message[] msgs = new Message[150];
       
       MessageReference[] refs1 = new MessageReference[150];

Copied: trunk/tests/src/org/jboss/test/messaging/core/paging/PagingStateTestBase.java (from rev 2781, trunk/tests/src/org/jboss/test/messaging/core/paging/base/PagingStateTestBase.java)
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/PagingStateTestBase.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/PagingStateTestBase.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,578 @@
+/*
+  * 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.paging;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
+import javax.transaction.TransactionManager;
+
+import org.jboss.jms.tx.MessagingXid;
+import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.DeliveryObserver;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.PersistenceManager;
+import org.jboss.messaging.core.contract.Queue;
+import org.jboss.messaging.core.contract.Receiver;
+import org.jboss.messaging.core.impl.IDManager;
+import org.jboss.messaging.core.impl.JDBCPersistenceManager;
+import org.jboss.messaging.core.impl.SimpleDelivery;
+import org.jboss.messaging.core.impl.message.SimpleMessageStore;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.core.impl.tx.TransactionRepository;
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.tools.jmx.ServiceContainer;
+import org.jboss.tm.TransactionManagerService;
+import org.jboss.util.id.GUID;
+
+/**
+ * 
+ * A PagingStateTestBase.
+ * 
+ * @author <a href="tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ */
+public class PagingStateTestBase extends MessagingTestCase
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+         
+   // Attributes ----------------------------------------------------
+
+   protected ServiceContainer sc;
+   protected PersistenceManager pm;
+   protected SimpleMessageStore ms;
+   protected TransactionRepository tr;
+   protected IDManager idm;
+
+   // Constructors --------------------------------------------------
+
+   public PagingStateTestBase(String name)
+   {
+      super(name);
+   }
+
+   // Public --------------------------------------------------------
+   
+   public void testEmpty()
+   {
+      
+   }
+
+   public void setUp() throws Exception
+   {
+      super.setUp();
+
+      sc = new ServiceContainer("all,-remoting,-security");
+      sc.start();
+
+      pm =
+         new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager(),
+                  sc.getPersistenceManagerSQLProperties(),
+                  true, true, true, false, 100);     
+      pm.start();
+      
+      idm = new IDManager("TRANSACTION_ID", 10, pm);
+      idm.start();
+      
+      ms = new SimpleMessageStore();
+      ms.start();
+      
+      tr = new TransactionRepository(pm, ms, idm);
+      tr.start();            
+   }
+   
+   
+   public void tearDown() throws Exception
+   {
+      pm.stop();
+      tr.stop();
+      ms.stop();
+      sc.stop();
+      
+      super.tearDown();
+   }
+   
+   protected Transaction createXATx() throws Exception
+   {
+      MessagingXid xid =
+         new MessagingXid(new GUID().toString().getBytes(), 345, new GUID().toString().getBytes());
+      
+      return tr.createTransaction(xid);
+   }
+
+   protected void assertSameIds(List ids, MessageReference[] refs, int start, int end)
+   {
+      assertNotNull(ids);
+      assertEquals(ids.size(), end - start + 1);
+      Iterator iter = ids.iterator();
+      int i = start;
+      while (iter.hasNext())
+      {
+         Long id = (Long)iter.next();
+         assertEquals(refs[i].getMessage().getMessageID(), id.longValue());
+         i++;
+      }
+   }
+   
+   class ConsumingReceiver implements Receiver
+   {
+      int numToConsume;
+      
+      int count;
+      
+      MessageReference[] refs;
+      
+      int consumeCount;
+      
+      boolean xa;
+      
+      boolean tx;
+      
+      SimpleDelivery[] dels;
+      
+      ConsumingReceiver(int numToConsume, MessageReference[] refs,
+                        int consumeCount, boolean tx, boolean xa) throws Exception
+      {
+         this.numToConsume = numToConsume;
+         
+         this.refs = refs;
+         
+         this.consumeCount = consumeCount;
+         
+         this.xa = xa;
+         
+         this.tx = tx;
+         
+         this.dels = new SimpleDelivery[numToConsume];
+      }
+
+      public synchronized Delivery handle(DeliveryObserver observer,
+                                          MessageReference ref, Transaction tx)
+      {  
+         if (count >= numToConsume)
+         {
+            return null;
+         }
+         
+         assertEquals(refs[consumeCount + count].getMessage().getMessageID(), ref.getMessage().getMessageID());
+         
+         SimpleDelivery del = new SimpleDelivery(observer, ref);
+         
+         dels[count] = del;
+         
+         count++;
+         
+         if (count == numToConsume)
+         {
+            notify();
+         }
+           
+         return del;                 
+      }      
+      
+      void acknowledge() throws Throwable
+      {
+         //Wait for them all to arrive first
+         
+         synchronized (this)
+         {
+         
+            while (count < numToConsume)
+            {
+               wait(10000);
+      
+               if (count < numToConsume)
+               {
+                  PagingStateTestBase.fail();
+                  return;
+               }
+            }
+         }
+         
+         Transaction theTx = null;
+         
+         if (tx)
+         {
+            if (xa)
+            {
+               theTx = createXATx();
+            }
+            else
+            {
+               theTx = tr.createTransaction();
+            }
+         }
+         
+         for (int i = 0; i < numToConsume; i++)
+         {
+            dels[i].acknowledge(theTx);
+         }
+         
+         if (tx)
+         {
+            if (xa)
+            {
+               theTx.prepare();
+               theTx.commit();
+            }
+            else
+            {
+               theTx.commit();
+            }
+         }    
+      }
+   }
+   
+   class CancellingReceiver implements Receiver
+   {
+      int numToCancel;
+      
+      int count;
+        
+      SimpleDelivery[] toCancel;
+      
+      CancellingReceiver(int numToConsume)
+         throws Exception
+      {
+         this.numToCancel = numToConsume;
+         
+         this.toCancel = new SimpleDelivery[numToCancel];
+         
+      }
+
+      public synchronized Delivery handle(DeliveryObserver observer,
+                                          MessageReference ref, Transaction tx)
+      {
+         if (count == numToCancel)
+         {
+            return null;
+         }
+         
+         SimpleDelivery del = new SimpleDelivery(observer, ref);
+         
+         toCancel[count] = del;                  
+         
+         count++;         
+         
+         if (count == numToCancel)
+         {
+            notify();
+         }
+         
+         return del;
+                  
+      }      
+      
+      public synchronized SimpleDelivery[] getToCancel() throws Exception
+      {
+         // Wait for them all to arrive first
+         
+         while (count < numToCancel)
+         {
+            wait(1000);
+            
+            if (count < numToCancel)
+            {
+               PagingStateTestBase.fail();
+               return null;
+            }
+         }
+         
+         return toCancel;
+         
+      }
+      
+      void cancel() throws Exception
+      {
+         //Wait for them all to arrive first
+         
+         synchronized (this)
+         {
+            
+            while (count < numToCancel)
+            {
+               wait(1000);
+               
+               if (count < numToCancel)
+               {
+                  PagingStateTestBase.fail();
+                  return;
+               }
+            }
+         }
+         
+         for (int i = numToCancel - 1; i >=0; i--)
+         {
+            try
+            {
+               toCancel[i].cancel();
+            }
+            catch (Throwable t)
+            {
+               log.error("Failed to cancel", t);
+               PagingStateTestBase.fail();
+            }
+         }
+      }
+   }
+
+   protected void consume(Queue queue, int consumeCount,
+         MessageReference[] refs, int num)
+      throws Throwable
+   {
+      ConsumingReceiver r = new ConsumingReceiver(num, refs, consumeCount, false, false);
+      queue.getLocalDistributor().add(r);
+      queue.deliver();
+      r.acknowledge();
+      queue.getLocalDistributor().remove(r);
+      //Need to give enough time for the call to handle to complete and return
+      //thus removing the ref
+      Thread.sleep(500);
+   }
+   
+   protected void consumeInTx(Queue queue, int consumeCount,
+         MessageReference[] refs, int num)
+      throws Throwable
+   {
+      ConsumingReceiver r = new ConsumingReceiver(num, refs, consumeCount, true, false);
+      queue.getLocalDistributor().add(r);
+      queue.deliver();
+      r.acknowledge();
+      queue.getLocalDistributor().remove(r);
+      //Need to give enough time for the call to handle to complete and return
+      //thus removing the ref
+      Thread.sleep(500);
+   }
+   
+   protected void consumeIn2PCTx(Queue queue, int consumeCount,
+         MessageReference[] refs, int num)
+      throws Throwable
+   {
+      ConsumingReceiver r = new ConsumingReceiver(num, refs, consumeCount, true, true);
+      queue.getLocalDistributor().add(r);
+      queue.deliver();
+      r.acknowledge();
+      queue.getLocalDistributor().remove(r);
+      //Need to give enough time for the call to handle to complete and return
+      //thus removing the ref
+      Thread.sleep(500);
+   }
+   
+   protected SimpleDelivery[] getDeliveries(Queue queue, int number) throws Exception
+   {
+      CancellingReceiver r1 = new CancellingReceiver(number);
+      queue.getLocalDistributor().add(r1);
+      queue.deliver();   
+      SimpleDelivery[] dels = r1.getToCancel();
+      queue.getLocalDistributor().remove(r1);
+      //Need to give enough time for the call to handle to complete and return
+      //thus removing the ref
+      Thread.sleep(500);      
+      
+      return dels;
+   }
+   
+   protected void cancelDeliveries(Queue queue, int number) throws Exception
+   {
+      CancellingReceiver r1 = new CancellingReceiver(number);
+      queue.getLocalDistributor().add(r1);
+      queue.deliver();   
+      r1.cancel();
+      queue.getLocalDistributor().remove(r1);
+      //Need to give enough time for the call to handle to complete and return
+      //thus removing the ref
+      Thread.sleep(500);      
+   }
+   
+   
+   protected List getReferenceIdsOrderedByOrd(long queueId) throws Exception
+   {
+      InitialContext ctx = new InitialContext();
+
+      TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
+      DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
+      
+      javax.transaction.Transaction txOld = mgr.suspend();
+      mgr.begin();
+
+      Connection conn = ds.getConnection();
+      
+      List msgIds = new ArrayList();
+
+      String sql =
+         "SELECT MESSAGE_ID, ORD, PAGE_ORD FROM JBM_MSG_REF WHERE CHANNEL_ID=? ORDER BY ORD";
+      PreparedStatement ps = conn.prepareStatement(sql);
+      ps.setLong(1, queueId);
+   
+      ResultSet rs = ps.executeQuery();
+            
+      while (rs.next())
+      {
+         long msgId = rs.getLong(1);
+
+         msgIds.add(new Long(msgId));
+      }
+      rs.close();
+      ps.close();
+       
+      conn.close();
+      
+      mgr.commit();
+
+      if (txOld != null)
+      {
+         mgr.resume(txOld);
+      }
+      
+      return msgIds;
+   }
+   
+   protected List getReferenceIdsOrderedByPageOrd(long queueId) throws Exception
+   {
+      InitialContext ctx = new InitialContext();
+
+      TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
+      DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
+      
+      javax.transaction.Transaction txOld = mgr.suspend();
+      mgr.begin();
+
+      Connection conn = ds.getConnection();
+      
+      List msgIds = new ArrayList();
+ 
+      String sql =
+         "SELECT MESSAGE_ID, ORD, PAGE_ORD FROM JBM_MSG_REF WHERE CHANNEL_ID=? ORDER BY PAGE_ORD";
+      PreparedStatement ps = conn.prepareStatement(sql);
+      ps.setLong(1, queueId);
+   
+      ResultSet rs = ps.executeQuery();
+            
+      while (rs.next())
+      {
+         long msgId = rs.getLong(1);     
+
+         msgIds.add(new Long(msgId));
+      }
+      rs.close();
+      ps.close();
+       
+      conn.close();
+
+      mgr.commit();
+
+      if (txOld != null)
+      {
+         mgr.resume(txOld);
+      }
+      
+      return msgIds;
+   }
+   
+   protected List getPagedReferenceIds(long queueId) throws Exception
+   {
+      InitialContext ctx = new InitialContext();
+
+      TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
+      DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
+      
+      javax.transaction.Transaction txOld = mgr.suspend();
+      mgr.begin();
+
+      Connection conn = ds.getConnection();
+      String sql =
+         "SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE " +
+         "CHANNEL_ID=? AND PAGE_ORD IS NOT NULL ORDER BY PAGE_ORD";
+
+      PreparedStatement ps = conn.prepareStatement(sql);
+      ps.setLong(1, queueId);
+   
+      ResultSet rs = ps.executeQuery();
+      
+      List msgIds = new ArrayList();
+      
+      while (rs.next())
+      {
+         long msgId = rs.getLong(1);
+         msgIds.add(new Long(msgId));
+      }
+      rs.close();
+      ps.close();
+      conn.close();
+
+      mgr.commit();
+
+      if (txOld != null)
+      {
+         mgr.resume(txOld);
+      }
+      
+      return msgIds;
+   }
+   
+   protected List getMessageIds() throws Exception
+   {
+      InitialContext ctx = new InitialContext();
+
+      TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
+      DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
+      
+      javax.transaction.Transaction txOld = mgr.suspend();
+      mgr.begin();
+
+      Connection conn = ds.getConnection();
+      String sql = "SELECT MESSAGE_ID FROM JBM_MSG ORDER BY MESSAGE_ID";
+      PreparedStatement ps = conn.prepareStatement(sql);
+      
+      ResultSet rs = ps.executeQuery();
+      
+      List msgIds = new ArrayList();
+      
+      while (rs.next())
+      {
+         long msgId = rs.getLong(1);
+         msgIds.add(new Long(msgId));
+      }
+      rs.close();
+      ps.close();
+      conn.close();
+
+      mgr.commit();
+
+      if (txOld != null)
+      {
+         mgr.resume(txOld);
+      }
+      
+      return msgIds;
+   }
+}

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/PagingTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/PagingTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/PagingTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -21,12 +21,12 @@
 */
 package org.jboss.test.messaging.core.paging;
 
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.CoreMessage;
-import org.jboss.messaging.core.message.SimpleMessageStore;
-import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.PersistenceManager;
+import org.jboss.messaging.core.impl.JDBCPersistenceManager;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.core.impl.message.CoreMessage;
+import org.jboss.messaging.core.impl.message.SimpleMessageStore;
 import org.jboss.test.messaging.MessagingTestCase;
 import org.jboss.test.messaging.tools.jmx.ServiceContainer;
 import org.jboss.test.messaging.util.CoreMessageFactory;
@@ -61,9 +61,7 @@
 
    public void testPaging() throws Exception
    {
-      PagingFilteredQueue p =
-         new PagingFilteredQueue("queue0", 1, ms, pm, true, true,
-                                 -1, null, 100, 20, 10);
+      MessagingQueue p = new MessagingQueue(1, "queue0", 1, ms, pm, true, -1, null, 100, 20, 10, false, false);
            
       CoreMessage m = null;
 

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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_2PCTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,13 +23,12 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.LockMap;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.test.messaging.core.paging.base.PagingStateTestBase;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.core.impl.SimpleDelivery;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.util.LockMap;
 import org.jboss.test.messaging.util.CoreMessageFactory;
 
 /**
@@ -65,8 +64,8 @@
    
    public void test1() throws Throwable
    {
-      PagingFilteredQueue queue = new PagingFilteredQueue("queue1", 1, ms, pm, true, true, -1, null, 100, 20, 10);
-            
+      MessagingQueue queue = new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, 100, 20, 10, false, false);
+      
       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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_NTTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,12 +23,11 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.LockMap;
-import org.jboss.test.messaging.core.paging.base.PagingStateTestBase;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.core.impl.SimpleDelivery;
+import org.jboss.messaging.util.LockMap;
 import org.jboss.test.messaging.util.CoreMessageFactory;
 
 /**
@@ -64,8 +63,8 @@
    
    public void test1() throws Throwable
    {
-      PagingFilteredQueue queue = new PagingFilteredQueue("queue1", 1, ms, pm, true, true, -1, null, 100, 20, 10);
-      
+      MessagingQueue queue = new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, 100, 20, 10, false, false);
+       
       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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_TTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,13 +23,12 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.LockMap;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.test.messaging.core.paging.base.PagingStateTestBase;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.core.impl.SimpleDelivery;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.util.LockMap;
 import org.jboss.test.messaging.util.CoreMessageFactory;
 
 /**
@@ -65,7 +64,7 @@
  
    public void test1() throws Throwable
    {
-      PagingFilteredQueue queue = new PagingFilteredQueue("queue1", 1, ms, pm, true, true, -1, null, 100, 20, 10);
+      MessagingQueue queue = new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, 100, 20, 10, false, false);
       
       Message[] msgs = new Message[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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_2PCTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,13 +23,12 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.LockMap;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.test.messaging.core.paging.base.PagingStateTestBase;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.core.impl.SimpleDelivery;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.util.LockMap;
 import org.jboss.test.messaging.util.CoreMessageFactory;
 
 /**
@@ -65,7 +64,7 @@
    
    public void test1() throws Throwable
    {
-      PagingFilteredQueue queue = new PagingFilteredQueue("queue1", 1, ms, pm, true, true, -1, null, 100, 20, 10);
+      MessagingQueue queue = new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, 100, 20, 10, false, false);
       
       Message[] msgs = new Message[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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_NTTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,12 +23,11 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.LockMap;
-import org.jboss.test.messaging.core.paging.base.PagingStateTestBase;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.core.impl.SimpleDelivery;
+import org.jboss.messaging.util.LockMap;
 import org.jboss.test.messaging.util.CoreMessageFactory;
 
 /**
@@ -64,7 +63,7 @@
    
    public void test1() throws Throwable
    {
-      PagingFilteredQueue queue = new PagingFilteredQueue("queue1", 1, ms, pm, true, true, -1, null, 100, 20, 10);
+      MessagingQueue queue = new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, 100, 20, 10, false, false);
       
       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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_TTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,13 +23,12 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.LockMap;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.test.messaging.core.paging.base.PagingStateTestBase;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.core.impl.SimpleDelivery;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.messaging.util.LockMap;
 import org.jboss.test.messaging.util.CoreMessageFactory;
 
 /**
@@ -65,8 +64,8 @@
    
    public void test1() throws Throwable
    {
-      PagingFilteredQueue queue = new PagingFilteredQueue("queue1", 1, ms, pm, true, true, -1, null, 100, 20, 10);
-      
+      MessagingQueue queue = new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, 100, 20, 10, false, false);
+        
       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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_ReloadTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -23,14 +23,13 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.message.SimpleMessageStore;
-import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
-import org.jboss.messaging.core.plugin.LockMap;
-import org.jboss.messaging.core.tx.TransactionRepository;
-import org.jboss.test.messaging.core.paging.base.PagingStateTestBase;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.impl.JDBCPersistenceManager;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.core.impl.message.SimpleMessageStore;
+import org.jboss.messaging.core.impl.tx.TransactionRepository;
+import org.jboss.messaging.util.LockMap;
 import org.jboss.test.messaging.util.CoreMessageFactory;
 
 /**
@@ -66,10 +65,8 @@
    
    public void testRecoverableQueueCrash() throws Throwable
    {
-      PagingFilteredQueue queue =
-         new PagingFilteredQueue("queue1", 1, ms, pm, true, true,
-                                 -1, null, 100, 20, 10);
-
+      MessagingQueue queue = new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, 100, 20, 10, false, false);
+      
       Message[] msgs = new Message[200];
       
       MessageReference[] refs = new MessageReference[200];
@@ -129,9 +126,8 @@
 
       tr.start();
          
-      PagingFilteredQueue queue2 =
-         new PagingFilteredQueue("queue1", 1, ms, pm, true, true,
-                                 -1, null, 100, 20, 10);
+      MessagingQueue queue2 = new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, 100, 20, 10, false, false);
+      
       queue2.deactivate();
       queue2.load();
       
@@ -166,10 +162,8 @@
    {
       //Non recoverable queue - eg temporary queue
       
-      PagingFilteredQueue queue =
-         new PagingFilteredQueue("queue1", 1, ms, pm, true, true,
-                                 -1, null, 100, 20, 10);
-      
+      MessagingQueue queue = new MessagingQueue(1, "queue1", 1, ms, pm, false, -1, null, 100, 20, 10, false, false);
+         	      
       Message[] msgs = new Message[200];
       
       MessageReference[] refs = new MessageReference[200];
@@ -229,9 +223,8 @@
       tr = new TransactionRepository(pm, ms, idm);
       tr.start();
 
-      PagingFilteredQueue queue2 =
-         new PagingFilteredQueue("queue1", 1, ms, pm, true, true,
-                                 -1, null, 100, 20, 10);
+      MessagingQueue queue2 = new MessagingQueue(1, "queue1", 1, ms, pm, false, -1, null, 100, 20, 10, false, false);
+      
       queue2.deactivate();
       queue2.load();
       
@@ -260,10 +253,8 @@
    {
       //Non recoverable queue - eg temporary queue
       
-      PagingFilteredQueue queue =
-         new PagingFilteredQueue("queue1", 1, ms, pm, true, true,
-                                 -1, null, 100, 20, 10);
-  
+      MessagingQueue queue = new MessagingQueue(1, "queue1", 1, ms, pm, false, -1, null, 100, 20, 10, false, false);
+        
       Message[] msgs = new Message[200];
       
       MessageReference[] refs = new MessageReference[200];

Deleted: trunk/tests/src/org/jboss/test/messaging/core/paging/base/PagingStateTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/base/PagingStateTestBase.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/base/PagingStateTestBase.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,578 +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.paging.base;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.naming.InitialContext;
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
-
-import org.jboss.jms.tx.MessagingXid;
-import org.jboss.messaging.core.Channel;
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.DeliveryObserver;
-import org.jboss.messaging.core.Receiver;
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.message.SimpleMessageStore;
-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;
-import org.jboss.tm.TransactionManagerService;
-import org.jboss.util.id.GUID;
-
-/**
- * 
- * A PagingStateTestBase.
- * 
- * @author <a href="tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class PagingStateTestBase extends MessagingTestCase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-         
-   // Attributes ----------------------------------------------------
-
-   protected ServiceContainer sc;
-   protected PersistenceManager pm;
-   protected SimpleMessageStore ms;
-   protected TransactionRepository tr;
-   protected IDManager idm;
-
-   // Constructors --------------------------------------------------
-
-   public PagingStateTestBase(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-   
-   public void testEmpty()
-   {
-      
-   }
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-
-      sc = new ServiceContainer("all,-remoting,-security");
-      sc.start();
-
-      pm =
-         new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager(),
-                  sc.getPersistenceManagerSQLProperties(),
-                  true, true, true, false, 100);     
-      pm.start();
-      
-      idm = new IDManager("TRANSACTION_ID", 10, pm);
-      idm.start();
-      
-      ms = new SimpleMessageStore();
-      ms.start();
-      
-      tr = new TransactionRepository(pm, ms, idm);
-      tr.start();            
-   }
-   
-   
-   public void tearDown() throws Exception
-   {
-      pm.stop();
-      tr.stop();
-      ms.stop();
-      sc.stop();
-      
-      super.tearDown();
-   }
-   
-   protected Transaction createXATx() throws Exception
-   {
-      MessagingXid xid =
-         new MessagingXid(new GUID().toString().getBytes(), 345, new GUID().toString().getBytes());
-      
-      return tr.createTransaction(xid);
-   }
-
-   protected void assertSameIds(List ids, MessageReference[] refs, int start, int end)
-   {
-      assertNotNull(ids);
-      assertEquals(ids.size(), end - start + 1);
-      Iterator iter = ids.iterator();
-      int i = start;
-      while (iter.hasNext())
-      {
-         Long id = (Long)iter.next();
-         assertEquals(refs[i].getMessage().getMessageID(), id.longValue());
-         i++;
-      }
-   }
-   
-   class ConsumingReceiver implements Receiver
-   {
-      int numToConsume;
-      
-      int count;
-      
-      MessageReference[] refs;
-      
-      int consumeCount;
-      
-      boolean xa;
-      
-      boolean tx;
-      
-      SimpleDelivery[] dels;
-      
-      ConsumingReceiver(int numToConsume, MessageReference[] refs,
-                        int consumeCount, boolean tx, boolean xa) throws Exception
-      {
-         this.numToConsume = numToConsume;
-         
-         this.refs = refs;
-         
-         this.consumeCount = consumeCount;
-         
-         this.xa = xa;
-         
-         this.tx = tx;
-         
-         this.dels = new SimpleDelivery[numToConsume];
-      }
-
-      public synchronized Delivery handle(DeliveryObserver observer,
-                                          MessageReference ref, Transaction tx)
-      {  
-         if (count >= numToConsume)
-         {
-            return null;
-         }
-         
-         assertEquals(refs[consumeCount + count].getMessage().getMessageID(), ref.getMessage().getMessageID());
-         
-         SimpleDelivery del = new SimpleDelivery(observer, ref);
-         
-         dels[count] = del;
-         
-         count++;
-         
-         if (count == numToConsume)
-         {
-            notify();
-         }
-           
-         return del;                 
-      }      
-      
-      void acknowledge() throws Throwable
-      {
-         //Wait for them all to arrive first
-         
-         synchronized (this)
-         {
-         
-            while (count < numToConsume)
-            {
-               wait(10000);
-      
-               if (count < numToConsume)
-               {
-                  PagingStateTestBase.fail();
-                  return;
-               }
-            }
-         }
-         
-         Transaction theTx = null;
-         
-         if (tx)
-         {
-            if (xa)
-            {
-               theTx = createXATx();
-            }
-            else
-            {
-               theTx = tr.createTransaction();
-            }
-         }
-         
-         for (int i = 0; i < numToConsume; i++)
-         {
-            dels[i].acknowledge(theTx);
-         }
-         
-         if (tx)
-         {
-            if (xa)
-            {
-               theTx.prepare();
-               theTx.commit();
-            }
-            else
-            {
-               theTx.commit();
-            }
-         }    
-      }
-   }
-   
-   class CancellingReceiver implements Receiver
-   {
-      int numToCancel;
-      
-      int count;
-        
-      SimpleDelivery[] toCancel;
-      
-      CancellingReceiver(int numToConsume)
-         throws Exception
-      {
-         this.numToCancel = numToConsume;
-         
-         this.toCancel = new SimpleDelivery[numToCancel];
-         
-      }
-
-      public synchronized Delivery handle(DeliveryObserver observer,
-                                          MessageReference ref, Transaction tx)
-      {
-         if (count == numToCancel)
-         {
-            return null;
-         }
-         
-         SimpleDelivery del = new SimpleDelivery(observer, ref);
-         
-         toCancel[count] = del;                  
-         
-         count++;         
-         
-         if (count == numToCancel)
-         {
-            notify();
-         }
-         
-         return del;
-                  
-      }      
-      
-      public synchronized SimpleDelivery[] getToCancel() throws Exception
-      {
-         // Wait for them all to arrive first
-         
-         while (count < numToCancel)
-         {
-            wait(1000);
-            
-            if (count < numToCancel)
-            {
-               PagingStateTestBase.fail();
-               return null;
-            }
-         }
-         
-         return toCancel;
-         
-      }
-      
-      void cancel() throws Exception
-      {
-         //Wait for them all to arrive first
-         
-         synchronized (this)
-         {
-            
-            while (count < numToCancel)
-            {
-               wait(1000);
-               
-               if (count < numToCancel)
-               {
-                  PagingStateTestBase.fail();
-                  return;
-               }
-            }
-         }
-         
-         for (int i = numToCancel - 1; i >=0; i--)
-         {
-            try
-            {
-               toCancel[i].cancel();
-            }
-            catch (Throwable t)
-            {
-               log.error("Failed to cancel", t);
-               PagingStateTestBase.fail();
-            }
-         }
-      }
-   }
-
-   protected void consume(Channel channel, int consumeCount,
-         MessageReference[] refs, int num)
-      throws Throwable
-   {
-      ConsumingReceiver r = new ConsumingReceiver(num, refs, consumeCount, false, false);
-      channel.add(r);
-      channel.deliver();
-      r.acknowledge();
-      channel.remove(r);
-      //Need to give enough time for the call to handle to complete and return
-      //thus removing the ref
-      Thread.sleep(500);
-   }
-   
-   protected void consumeInTx(Channel channel, int consumeCount,
-         MessageReference[] refs, int num)
-      throws Throwable
-   {
-      ConsumingReceiver r = new ConsumingReceiver(num, refs, consumeCount, true, false);
-      channel.add(r);
-      channel.deliver();
-      r.acknowledge();
-      channel.remove(r);
-      //Need to give enough time for the call to handle to complete and return
-      //thus removing the ref
-      Thread.sleep(500);
-   }
-   
-   protected void consumeIn2PCTx(Channel channel, int consumeCount,
-         MessageReference[] refs, int num)
-      throws Throwable
-   {
-      ConsumingReceiver r = new ConsumingReceiver(num, refs, consumeCount, true, true);
-      channel.add(r);
-      channel.deliver();
-      r.acknowledge();
-      channel.remove(r);
-      //Need to give enough time for the call to handle to complete and return
-      //thus removing the ref
-      Thread.sleep(500);
-   }
-   
-   protected SimpleDelivery[] getDeliveries(Channel channel, int number) throws Exception
-   {
-      CancellingReceiver r1 = new CancellingReceiver(number);
-      channel.add(r1);
-      channel.deliver();   
-      SimpleDelivery[] dels = r1.getToCancel();
-      channel.remove(r1);
-      //Need to give enough time for the call to handle to complete and return
-      //thus removing the ref
-      Thread.sleep(500);      
-      
-      return dels;
-   }
-   
-   protected void cancelDeliveries(Channel channel, int number) throws Exception
-   {
-      CancellingReceiver r1 = new CancellingReceiver(number);
-      channel.add(r1);
-      channel.deliver();   
-      r1.cancel();
-      channel.remove(r1);
-      //Need to give enough time for the call to handle to complete and return
-      //thus removing the ref
-      Thread.sleep(500);      
-   }
-   
-   
-   protected List getReferenceIdsOrderedByOrd(long channelId) throws Exception
-   {
-      InitialContext ctx = new InitialContext();
-
-      TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
-      DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
-      
-      javax.transaction.Transaction txOld = mgr.suspend();
-      mgr.begin();
-
-      Connection conn = ds.getConnection();
-      
-      List msgIds = new ArrayList();
-
-      String sql =
-         "SELECT MESSAGE_ID, ORD, PAGE_ORD FROM JBM_MSG_REF WHERE CHANNEL_ID=? ORDER BY ORD";
-      PreparedStatement ps = conn.prepareStatement(sql);
-      ps.setLong(1, channelId);
-   
-      ResultSet rs = ps.executeQuery();
-            
-      while (rs.next())
-      {
-         long msgId = rs.getLong(1);
-
-         msgIds.add(new Long(msgId));
-      }
-      rs.close();
-      ps.close();
-       
-      conn.close();
-      
-      mgr.commit();
-
-      if (txOld != null)
-      {
-         mgr.resume(txOld);
-      }
-      
-      return msgIds;
-   }
-   
-   protected List getReferenceIdsOrderedByPageOrd(long channelId) throws Exception
-   {
-      InitialContext ctx = new InitialContext();
-
-      TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
-      DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
-      
-      javax.transaction.Transaction txOld = mgr.suspend();
-      mgr.begin();
-
-      Connection conn = ds.getConnection();
-      
-      List msgIds = new ArrayList();
- 
-      String sql =
-         "SELECT MESSAGE_ID, ORD, PAGE_ORD FROM JBM_MSG_REF WHERE CHANNEL_ID=? ORDER BY PAGE_ORD";
-      PreparedStatement ps = conn.prepareStatement(sql);
-      ps.setLong(1, channelId);
-   
-      ResultSet rs = ps.executeQuery();
-            
-      while (rs.next())
-      {
-         long msgId = rs.getLong(1);     
-
-         msgIds.add(new Long(msgId));
-      }
-      rs.close();
-      ps.close();
-       
-      conn.close();
-
-      mgr.commit();
-
-      if (txOld != null)
-      {
-         mgr.resume(txOld);
-      }
-      
-      return msgIds;
-   }
-   
-   protected List getPagedReferenceIds(long channelId) throws Exception
-   {
-      InitialContext ctx = new InitialContext();
-
-      TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
-      DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
-      
-      javax.transaction.Transaction txOld = mgr.suspend();
-      mgr.begin();
-
-      Connection conn = ds.getConnection();
-      String sql =
-         "SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE " +
-         "CHANNEL_ID=? AND PAGE_ORD IS NOT NULL ORDER BY PAGE_ORD";
-
-      PreparedStatement ps = conn.prepareStatement(sql);
-      ps.setLong(1, channelId);
-   
-      ResultSet rs = ps.executeQuery();
-      
-      List msgIds = new ArrayList();
-      
-      while (rs.next())
-      {
-         long msgId = rs.getLong(1);
-         msgIds.add(new Long(msgId));
-      }
-      rs.close();
-      ps.close();
-      conn.close();
-
-      mgr.commit();
-
-      if (txOld != null)
-      {
-         mgr.resume(txOld);
-      }
-      
-      return msgIds;
-   }
-   
-   protected List getMessageIds() throws Exception
-   {
-      InitialContext ctx = new InitialContext();
-
-      TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
-      DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
-      
-      javax.transaction.Transaction txOld = mgr.suspend();
-      mgr.begin();
-
-      Connection conn = ds.getConnection();
-      String sql = "SELECT MESSAGE_ID FROM JBM_MSG ORDER BY MESSAGE_ID";
-      PreparedStatement ps = conn.prepareStatement(sql);
-      
-      ResultSet rs = ps.executeQuery();
-      
-      List msgIds = new ArrayList();
-      
-      while (rs.next())
-      {
-         long msgId = rs.getLong(1);
-         msgIds.add(new Long(msgId));
-      }
-      rs.close();
-      ps.close();
-      conn.close();
-
-      mgr.commit();
-
-      if (txOld != null)
-      {
-         mgr.resume(txOld);
-      }
-      
-      return msgIds;
-   }
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/persistence/JDBCUtilTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/persistence/JDBCUtilTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/persistence/JDBCUtilTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,84 +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.persistence;
-
-import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.messaging.util.JDBCUtil;
-
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- */
-public class JDBCUtilTest extends MessagingTestCase
-{
-   // Attributes ----------------------------------------------------
-
-   // Constructors --------------------------------------------------
-
-   public JDBCUtilTest(String name)
-   {
-      super(name);
-   }
-
-   public void testStatementToStringOneArgument()
-   {
-      String sql = "INSERT INTO A (B) values(?)";
-      String statement = JDBCUtil.statementToString(sql, "X");
-      assertEquals("INSERT INTO A (B) values(X)", statement);
-   }
-
-   public void testStatementToStringTwoArguments()
-   {
-      String sql = "INSERT INTO A (B, C) values(?, ?)";
-      String statement = JDBCUtil.statementToString(sql, "X", "Y");
-      assertEquals("INSERT INTO A (B, C) values(X, Y)", statement);
-   }
-
-   public void testStatementToStringWitNull()
-   {
-      String sql = "INSERT INTO A (B, C) values(?, ?)";
-      String statement = JDBCUtil.statementToString(sql, null, "Y");
-      assertEquals("INSERT INTO A (B, C) values(null, Y)", statement);
-   }
-
-
-   public void testExtraArguments()
-   {
-      String sql = "INSERT INTO A (B, C) values(?, ?)";
-      String statement = JDBCUtil.statementToString(sql, "X", "Y", "Z");
-      assertEquals("INSERT INTO A (B, C) values(X, Y)", statement);
-   }
-
-   public void testNotEnoughArguments()
-   {
-      String sql = "INSERT INTO A (B, C, D) values(?, ?, ?)";
-      String statement = JDBCUtil.statementToString(sql, "X", "Y");
-      assertEquals("INSERT INTO A (B, C, D) values(X, Y, ?)", statement);
-   }
-
-
-
-
-}
-
-

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/IdManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/IdManagerTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/IdManagerTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,138 +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.jms.delegate.IDBlock;
-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.test.messaging.MessagingTestCase;
-import org.jboss.test.messaging.tools.ServerManagement;
-import org.jboss.test.messaging.tools.jmx.ServiceContainer;
-
-/**
- * 
- * A IdManagerTest.
- * 
- * @author <a href="tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class IdManagerTest extends MessagingTestCase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-   protected ServiceContainer sc;
-
-   protected PersistenceManager pm;
-   
-   // Constructors --------------------------------------------------
-
-   public IdManagerTest(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(),
-                  sc.getPersistenceManagerSQLProperties(),
-                  true, true, true, false, 100);     
-      pm.start();
-      
-      pm.start();
-            
-      log.debug("setup done");
-   }
-
-   public void tearDown() throws Exception
-   {      
-      if (!ServerManagement.isRemote())
-      {
-         sc.stop();
-         sc = null;
-      }
-      pm.stop();
-      super.tearDown();
-   }
-   
-   public void test1() throws Exception
-   {
-      IDManager idm = new IDManager("test_counter", 1000, pm);
-      idm.start();
-      
-      int blockSize = 37;
-            
-      long nextLow = Long.MIN_VALUE;
-      
-      for (int i = 0; i < 1000; i++)
-      {
-         IDBlock block = idm.getIDBlock(blockSize);
-                   
-         assertTrue(block.getLow() >= nextLow);
-         
-         assertEquals(blockSize, 1 + block.getHigh() - block.getLow());
-         
-         nextLow = block.getHigh() + 1;         
-      }
-      
-      idm.stop();
-   }
-   
-   public void test2() throws Exception
-   {
-      IDManager idm = new IDManager("test_counter2", 100, pm);
-      idm.start();
-         
-      for (int i = 0; i < 1000; i++)
-      {
-         long id = idm.getID();
-         
-         assertEquals(i, id);
-      }
-      
-      idm.stop();
-   }
-
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-
-}
-

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,1592 +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 java.io.Serializable;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.naming.InitialContext;
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
-import javax.transaction.xa.Xid;
-
-import org.jboss.messaging.core.Channel;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.message.SimpleMessageStore;
-import org.jboss.messaging.core.plugin.IDManager;
-import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
-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.SimpleChannel;
-import org.jboss.test.messaging.tools.ServerManagement;
-import org.jboss.test.messaging.tools.jmx.ServiceContainer;
-import org.jboss.test.messaging.util.CoreMessageFactory;
-import org.jboss.tm.TransactionManagerService;
-import org.jboss.util.id.GUID;
-
-
-/**
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>1.1</tt>
- *
- * JDBCPersistenceManagerTest.java,v 1.1 2006/02/22 17:33:44 timfox Exp
- */
-public class JDBCPersistenceManagerTest extends MessagingTestCase
-{
-   // Attributes ----------------------------------------------------
-
-   protected ServiceContainer sc;
-   
-   protected JDBCPersistenceManager pm;
-   
-   protected MessageStore ms;
-   
-   
-   // Constructors --------------------------------------------------
-
-   public JDBCPersistenceManagerTest(String name)
-   {
-      super(name);
-   }
-
-   public void setUp() throws Exception
-   {
-      if (ServerManagement.isRemote())
-      {
-         fail("This test is not supposed to run remotely!");
-      }
-
-      super.setUp();
-
-      sc = new ServiceContainer("all");
-      sc.start();                
-      
-   }
-   
-   protected void doSetup(boolean batch, boolean useBinaryStream,
-                          boolean trailingByte, int maxParams) throws Throwable
-   {
-      pm = createPM(batch, useBinaryStream, trailingByte, maxParams);         
-      ms = new SimpleMessageStore();      
-   }
-   
-   protected JDBCPersistenceManager createPM(boolean batch, boolean useBinaryStream,
-                                             boolean trailingByte, int maxParams) throws Throwable
-   {      
-      JDBCPersistenceManager p =
-         new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager(),
-                  sc.getPersistenceManagerSQLProperties(),
-                  true, batch, useBinaryStream, trailingByte, maxParams);
-      p.start();
-      return p;
-   }
-
-   public void tearDown() throws Exception
-   {
-      if (!ServerManagement.isRemote())
-      {
-         sc.stop();
-         sc = null;
-      }
-      pm.stop();
-      ms.stop();
-      super.tearDown();
-   }
-   
-   
-   public void testAddRemoveGetReferences_Batch() throws Throwable
-   {
-      addRemoveGetReferences(true);
-   }
-   
-   public void testAddRemoveGetReferences_NoBatch() throws Throwable
-   {
-      addRemoveGetReferences(false);
-   }
-   
-   
-   
-         
-   public void testAddRemoveReference() throws Throwable
-   {
-      doSetup(false, false, false, 100);
-      
-      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());
-            
-      }
-   }
-   
-   // Trailing zero
-   // -----------------
-   
-   // Binary Stream
-   
-   //non batch
-   
-   public void testCommit_NotXA_Long_NB_BS_TZ() throws Throwable
-   {
-      doTransactionCommit(false, false, true, true);
-   }
-   
-   public void testCommit_XA_Long_NB_BS_TZ() throws Throwable
-   {
-      doTransactionCommit(true, false, true, true);
-   }
-
-   public void testRollback_NotXA_Long_NB_BS_TZ() throws Throwable
-   {
-      doTransactionRollback(false, false, true, true);
-   }
-       
-   public void testRollback_XA_Long_NB_BS_TZ() throws Throwable
-   {
-      doTransactionRollback(true, false, true, true);
-   }
-   
-
-   //batch
-   
-   public void testCommit_NotXA_Long_B_BS_TZ() throws Throwable
-   {
-      doTransactionCommit(false, true, true, true);
-   }
-     
-   public void testCommit_XA_Long_B_BS_TZ() throws Throwable
-   {
-      doTransactionCommit(true, true, true, true);
-   }
-
-   public void testRollback_NotXA_Long_B_BS_TZ() throws Throwable
-   {
-      doTransactionRollback(false, true, true, true);
-   }
-        
-   public void testRollback_XA_Long_B_BS_TZ() throws Throwable
-   {
-      doTransactionRollback(true, true, true, true);
-   }
-   
-   // No binary stream
-   
-   //non batch
-   
-   public void testCommit_NotXA_Long_NB_BNS_TZ() throws Throwable
-   {
-      doTransactionCommit(false, false, false, true);
-   }
-   
-   public void testCommit_XA_Long_NB_NBS_TZ() throws Throwable
-   {
-      doTransactionCommit(true, false, false, true);
-   }
-
-   public void testRollback_NotXA_Long_NB_NBS_TZ() throws Throwable
-   {
-      doTransactionRollback(false, false, false, true);
-   }
-       
-   public void testRollback_XA_Long_NB_NBS_TZ() throws Throwable
-   {
-      doTransactionRollback(true, false, false, true);
-   }
-   
-
-   //batch
-   
-   public void testCommit_NotXA_Long_B_NBS_TZ() throws Throwable
-   {
-      doTransactionCommit(false, true, false, true);
-   }
-     
-   public void testCommit_XA_Long_B_NBS_TZ() throws Throwable
-   {
-      doTransactionCommit(true, true, false, true);
-   }
-
-   public void testRollback_NotXA_Long_B_NBS_TZ() throws Throwable
-   {
-      doTransactionRollback(false, true, false, true);
-   }
-        
-   public void testRollback_XA_Long_B_NBS_TZ() throws Throwable
-   {
-      doTransactionRollback(true, true, false, true);
-   }
-   
-       
-   // Non trailing zero
-   // -----------------
-   
-   // Binary Stream
-   
-   //non batch
-   
-   public void testCommit_NotXA_Long_NB_BS_NTZ() throws Throwable
-   {
-      doTransactionCommit(false, false, true, false);
-   }
-   
-   public void testCommit_XA_Long_NB_BS_NTZ() throws Throwable
-   {
-      doTransactionCommit(true, false, true, false);
-   }
-
-   public void testRollback_NotXA_Long_NB_BS_NTZ() throws Throwable
-   {
-      doTransactionRollback(false, false, true, false);
-   }
-       
-   public void testRollback_XA_Long_NB_BS_NTZ() throws Throwable
-   {
-      doTransactionRollback(true, false, true, false);
-   }
-   
-
-   //batch
-   
-   public void testCommit_NotXA_Long_B_BS_NTZ() throws Throwable
-   {
-      doTransactionCommit(false, true, true, false);
-   }
-     
-   public void testCommit_XA_Long_B_BS_NTZ() throws Throwable
-   {
-      doTransactionCommit(true, true, true, false);
-   }
-
-   public void testRollback_NotXA_Long_B_BS_NTZ() throws Throwable
-   {
-      doTransactionRollback(false, true, true, false);
-   }
-        
-   public void testRollback_XA_Long_B_BS_NTZ() throws Throwable
-   {
-      doTransactionRollback(true, true, true, false);
-   }
-   
-   // No binary stream
-   
-   //non batch
-   
-   public void testCommit_NotXA_Long_NB_BNS_NTZ() throws Throwable
-   {
-      doTransactionCommit(false, false, false, false);
-   }
-   
-   public void testCommit_XA_Long_NB_NBS_NTZ() throws Throwable
-   {
-      doTransactionCommit(true, false, false, false);
-   }
-
-   public void testRollback_NotXA_Long_NB_NBS_NTZ() throws Throwable
-   {
-      doTransactionRollback(false, false, false, false);
-   }
-       
-   public void testRollback_XA_Long_NB_NBS_NTZ() throws Throwable
-   {
-      doTransactionRollback(true, false, false, false);
-   }
-   
-
-   //batch
-   
-   public void testCommit_NotXA_Long_B_NBS_NTZ() throws Throwable
-   {
-      doTransactionCommit(false, true, false, false);
-   }
-     
-   public void testCommit_XA_Long_B_NBS_NTZ() throws Throwable
-   {
-      doTransactionCommit(true, true, false, false);
-   }
-
-   public void testRollback_NotXA_Long_B_NBS_NTZ() throws Throwable
-   {
-      doTransactionRollback(false, true, false, false);
-   }
-        
-   public void testRollback_XA_Long_B_NBS_NTZ() throws Throwable
-   {
-      doTransactionRollback(true, true, false, false);
-   }
-   
-   
-   
-   
-   protected void addRemoveGetReferences(boolean batch) throws Throwable
-   {
-      doSetup(false, false, false, 100);
-      
-      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.pageReferences(channel1.getChannelID(), refs, false);
-      
-      refs = new ArrayList();
-      refs.add(ref11);
-      refs.add(ref12);
-      refs.add(ref13);
-      refs.add(ref14);
-      refs.add(ref15);
-    
-      pm.pageReferences(channel2.getChannelID(), refs, false);
-                  
-      List refIds = getReferenceIds(channel1.getChannelID());
-      assertNotNull(refIds);
-      assertEquals(10, refIds.size());
-      assertTrue(refIds.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref2.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref3.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref4.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref5.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref6.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref7.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref8.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref9.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref10.getMessage().getMessageID())));
-      
-      refIds = getReferenceIds(channel2.getChannelID());
-      assertNotNull(refIds);
-      assertEquals(5, refIds.size());
-      assertTrue(refIds.contains(new Long(ref11.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref12.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref13.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref14.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref15.getMessage().getMessageID())));
-     
-      
-      List msgs = getMessageIds();
-      assertNotNull(msgs);
-      assertEquals(10, msgs.size());
-      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref3.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref4.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref5.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref6.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref7.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref8.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref9.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref10.getMessage().getMessageID())));
-      
-      List msgIds = new ArrayList();
-      msgIds.add(new Long(ref3.getMessage().getMessageID()));
-      msgIds.add(new Long(ref4.getMessage().getMessageID()));
-      msgIds.add(new Long(ref7.getMessage().getMessageID()));
-      msgIds.add(new Long(ref9.getMessage().getMessageID()));
-      msgIds.add(new Long(ref1.getMessage().getMessageID()));
-      
-      List ms = pm.getMessages(msgIds);
-      assertNotNull(ms);
-      assertEquals(5, ms.size());
-      assertTrue(containsMessage(ms, ref3.getMessage().getMessageID()));
-      assertTrue(containsMessage(ms, ref4.getMessage().getMessageID()));
-      assertTrue(containsMessage(ms, ref7.getMessage().getMessageID()));
-      assertTrue(containsMessage(ms, ref9.getMessage().getMessageID()));
-      assertTrue(containsMessage(ms, ref1.getMessage().getMessageID()));
-      
-      refs = new ArrayList();
-      refs.add(ref12);
-      refs.add(ref13);
-      refs.add(ref14);
-      refs.add(ref15);
-      pm.removeDepagedReferences(channel2.getChannelID(), refs);
-      
-      refIds = getReferenceIds(channel2.getChannelID());
-      assertNotNull(refIds);
-      assertEquals(1, refIds.size());
-      assertTrue(refIds.contains(new Long(ref11.getMessage().getMessageID())));
-      
-      ms = getMessageIds();
-
-      assertNotNull(ms);
-      assertEquals(10, ms.size());
-      
-      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref3.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref4.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref5.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref6.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref7.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref8.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref9.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref10.getMessage().getMessageID())));
-     
-      
-      refs = new ArrayList();
-      refs.add(ref1);
-      refs.add(ref2);
-      refs.add(ref3);
-      pm.removeDepagedReferences(channel1.getChannelID(), refs);
-      
-      refIds = getReferenceIds(channel1.getChannelID());
-      assertNotNull(refIds);
-      assertEquals(7, refIds.size());
-      assertTrue(refIds.contains(new Long(ref4.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref5.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref6.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref7.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref8.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref9.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref10.getMessage().getMessageID())));
-     
-      
-      ms = getMessageIds();
-        
-      assertNotNull(ms);
-      assertEquals(8, ms.size());
-      
-      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref4.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref5.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref6.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref7.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref8.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref9.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref10.getMessage().getMessageID())));
-      
-      refs = new ArrayList();
-      refs.add(ref11);
-      pm.removeDepagedReferences(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.removeDepagedReferences(channel1.getChannelID(), refs);
-      
-      ms = getMessageIds();
-      assertNotNull(ms);
-      assertEquals(0, ms.size());
-   }
-   
-   public void testPageOrders() throws Throwable
-   {
-      doSetup(false, false, false, 100);
-      
-      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.pageReferences(channel.getChannelID(), refs, false); 
-      
-      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);
-      
-      pm.updatePageOrder(channel.getChannelID(), refs);
-      
-      List refInfos = pm.getPagedReferenceInfos(channel.getChannelID(), 0, 10);
-      
-      assertNotNull(refInfos);
-      
-      assertEquals(10, refInfos.size());
-      
-      assertEquals(ref1.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
-      assertEquals(ref2.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
-      assertEquals(ref3.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
-      assertEquals(ref4.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
-      assertEquals(ref5.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());
-      assertEquals(ref6.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(5)).getMessageId());
-      assertEquals(ref7.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(6)).getMessageId());
-      assertEquals(ref8.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(7)).getMessageId());
-      assertEquals(ref9.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(8)).getMessageId());
-      assertEquals(ref10.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(9)).getMessageId());
-      
-      refInfos = pm.getPagedReferenceInfos(channel.getChannelID(), 3, 5);
-      
-      assertNotNull(refInfos);
-      
-      assertEquals(5, refInfos.size());
-      
-      assertEquals(ref4.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
-      assertEquals(ref5.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
-      assertEquals(ref6.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
-      assertEquals(ref7.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
-      assertEquals(ref8.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());
-    
-      pm.updateReferencesNotPagedInRange(channel.getChannelID(), 0, 3, 4);
-      
-      refInfos = pm.getPagedReferenceInfos(channel.getChannelID(), 5, 5);
-      
-      assertNotNull(refInfos);
-      
-      assertEquals(5, refInfos.size());
-          
-      assertEquals(ref6.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
-      assertEquals(ref7.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
-      assertEquals(ref8.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
-      assertEquals(ref9.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
-      assertEquals(ref10.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());                
-   }
-     
-   public void testGetMessages() throws Throwable
-   {
-      doSetup(false, false, false, 100);
-      
-      Channel channel = new SimpleChannel(0, 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]);
-      
-      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);
-      
-      List refIds = getReferenceIds(channel.getChannelID());
-      assertNotNull(refIds);
-      assertEquals(10, refIds.size());
-      assertTrue(refIds.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref2.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref3.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref4.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref5.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref6.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref7.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref8.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref9.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref10.getMessage().getMessageID())));
-      
-      List msgs = getMessageIds();
-      assertNotNull(msgs);
-      assertEquals(10, msgs.size());
-      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref3.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref4.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref5.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref6.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref7.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref8.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref9.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref10.getMessage().getMessageID())));
-      
-      List msgIds = new ArrayList();
-      msgIds.add(new Long(ref3.getMessage().getMessageID()));
-      msgIds.add(new Long(ref4.getMessage().getMessageID()));
-      msgIds.add(new Long(ref7.getMessage().getMessageID()));
-      msgIds.add(new Long(ref9.getMessage().getMessageID()));
-      msgIds.add(new Long(ref1.getMessage().getMessageID()));
-      
-      List ms = pm.getMessages(msgIds);
-      assertNotNull(ms);
-      assertEquals(5, ms.size());
-        
-      assertTrue(containsMessage(ms, ref3.getMessage().getMessageID()));
-      assertTrue(containsMessage(ms, ref4.getMessage().getMessageID()));
-      assertTrue(containsMessage(ms, ref7.getMessage().getMessageID()));
-      assertTrue(containsMessage(ms, ref9.getMessage().getMessageID()));
-      assertTrue(containsMessage(ms, ref1.getMessage().getMessageID()));
-        
-   }
-   
-   public void testGetInitialRefInfos() throws Throwable
-   {
-      doSetup(false, false, false, 100);
-      
-      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.pageReferences(channel.getChannelID(), refs, false); 
-      
-      //First load exactly 10
-      PersistenceManager.InitialLoadInfo info = pm.loadFromStart(channel.getChannelID(), 10);
-      
-      assertNull(info.getMinPageOrdering());
-      assertNull(info.getMaxPageOrdering());
-      
-      List refInfos = info.getRefInfos();
-      
-      assertNotNull(refInfos);
-      assertEquals(10, refInfos.size());
-      
-      assertEquals(ref1.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
-      assertEquals(ref2.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
-      assertEquals(ref3.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
-      assertEquals(ref4.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
-      assertEquals(ref5.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());
-      assertEquals(ref6.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(5)).getMessageId());
-      assertEquals(ref7.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(6)).getMessageId());
-      assertEquals(ref8.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(7)).getMessageId());
-      assertEquals(ref9.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(8)).getMessageId());
-      assertEquals(ref10.getMessage().getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(9)).getMessageId());          
-   }
-      
-   
-   protected boolean containsMessage(List msgs, long msgId)
-   {
-      Iterator iter = msgs.iterator();
-      while (iter.hasNext())
-      {
-         Message m = (Message)iter.next();
-         if (m.getMessageID() == msgId)
-         {
-            return true;
-         }           
-      }
-      return false;
-   }
-   
-   public void testGetMessagesMaxParams() throws Throwable
-   {
-      doSetup(false, false, false, 5);
-      
-      Channel channel = new SimpleChannel(0, 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]);
-      
-      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);
-      
-      List refIds = getReferenceIds(channel.getChannelID());
-      assertNotNull(refIds);
-      assertEquals(10, refIds.size());
-      assertTrue(refIds.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref2.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref3.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref4.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref5.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref6.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref7.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref8.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref9.getMessage().getMessageID())));
-      assertTrue(refIds.contains(new Long(ref10.getMessage().getMessageID())));
-      
-      List msgs = getMessageIds();
-      assertNotNull(msgs);
-      assertEquals(10, msgs.size());
-      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref3.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref4.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref5.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref6.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref7.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref8.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref9.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref10.getMessage().getMessageID())));
-      
-      List msgIds = new ArrayList();
-      msgIds.add(new Long(ref3.getMessage().getMessageID()));
-      msgIds.add(new Long(ref4.getMessage().getMessageID()));
-      msgIds.add(new Long(ref7.getMessage().getMessageID()));
-      msgIds.add(new Long(ref9.getMessage().getMessageID()));
-      msgIds.add(new Long(ref1.getMessage().getMessageID()));
-      
-      List ms = pm.getMessages(msgIds);
-      assertNotNull(ms);
-      assertEquals(5, ms.size());
-      assertTrue(containsMessage(ms, ref3.getMessage().getMessageID()));
-      assertTrue(containsMessage(ms, ref4.getMessage().getMessageID()));
-      assertTrue(containsMessage(ms, ref7.getMessage().getMessageID()));
-      assertTrue(containsMessage(ms, ref9.getMessage().getMessageID()));
-      assertTrue(containsMessage(ms, ref1.getMessage().getMessageID()));   
-   }
-   
-   
-   //Commented out until recovery work is complete
-
-//   public void testRetrievePreparedTransactions() throws Throwable
-//   {
-//      doSetup(false, 100);
-//      
-//      Channel channel = new SimpleChannel(0, ms);
-//      
-//      TransactionRepository txRep = new TransactionRepository(pm, new IDManager("TRANSACTION_ID", 10, pm));
-//      txRep.start();
-//
-//      Message[] messages = createMessages(10);
-//      
-//      Xid[] xids = new Xid[messages.length];
-//      Transaction[] txs = new Transaction[messages.length];
-//      
-//      for (int i = 0; i < messages.length; i++)
-//      {         
-//         xids[i] = new MockXid();
-//         txs[i] = txRep.createTransaction(xids[i]);
-//         MessageReference ref = ms.reference(messages[i]);
-//         pm.addReference(channel.getChannelID(), ref, txs[i]);
-//         txs[i].prepare();
-//      }
-//      
-//      List txList = pm.retrievePreparedTransactions();
-//      assertNotNull(txList);
-//      assertEquals(messages.length, txList.size());
-//      
-//      for (int i = 0; i < xids.length; i++)
-//      {
-//         Xid xid = xids[i];
-//         assertTrue(txList.contains(xid));
-//      }
-//      
-//      //rollback the txs
-//      for (int i = 0; i < txs.length; i++)
-//      {
-//         txs[i].rollback();
-//      }   
-//   }
-   
-   protected Message createMessage(byte i, boolean reliable) throws Throwable
-   {
-      Map headers = generateFilledMap(true);
-
-      return CoreMessageFactory.
-         createCoreMessage(i,
-                           reliable,
-                           System.currentTimeMillis() + 1000 * 60 * 60,
-                           System.currentTimeMillis(),
-                           (byte)(i % 10),
-                           headers,
-                           i % 2 == 0 ? new WibblishObject() : null);
-   }
-   
-   protected Message[] createMessages(int num) throws Throwable
-   {
-      //Generate some messages with a good range of attribute values
-      Message[] messages = new Message[num];
-      for (int i = 0; i < num; i++)
-      {            
-         messages[i] = createMessage((byte)i, true);
-      }
-      return messages;
-   }
-   
-   protected void checkEquivalent(Message m1, Message m2) throws Throwable
-   {
-      if (m1 == m2)
-      {
-         fail();
-      }
-      
-      if (m1 == null || m2 == null)
-      {
-         fail();
-      }
-      
-      //Attributes from org.jboss.messaging.core.Message
-      assertEquals(m1.getMessageID(), m2.getMessageID());
-      assertEquals(m1.isReliable(), m2.isReliable());
-      assertEquals(m1.getExpiration(), m2.getExpiration());
-      assertEquals(m1.isExpired(), m2.isExpired());
-      assertEquals(m1.getTimestamp(), m2.getTimestamp());
-      assertEquals(m1.getPriority(), m2.getPriority());
-      Map m1Headers = m1.getHeaders();
-      Map m2Headers = m2.getHeaders();
-      checkMapsEquivalent(m1Headers, m2Headers);
-      checkMapsEquivalent(m2Headers, m1Headers);
-      
-      if (m1.getPayload() instanceof byte[] && m2.getPayload() instanceof byte[])
-      {
-         this.checkByteArraysEqual((byte[])m1.getPayload(), (byte[])m2.getPayload());
-      }
-      else if (m1.getPayload() instanceof Map && m2.getPayload() instanceof Map)
-      {
-         this.checkMapsEquivalent((Map)m1.getPayload(), (Map)m2.getPayload());
-      }
-      else if (m1.getPayload() instanceof List && m2.getPayload() instanceof List)
-      {
-         this.checkListsEquivalent((List)m1.getPayload(), (List)m2.getPayload());
-      }
-      else
-      {      
-         assertEquals(m1.getPayload(), m2.getPayload());
-      }
-      
-   }
-   
-   protected void checkMapsEquivalent(Map headers1, Map headers2)
-   {
-      Iterator iter = headers1.entrySet().iterator();
-      while (iter.hasNext())
-      {
-         Map.Entry entry1 = (Map.Entry)iter.next();
-         Object value2 = headers2.get(entry1.getKey());
-         assertNotNull(value2);
-         if (value2 instanceof byte[])
-         {
-            checkByteArraysEqual((byte[])entry1.getValue(), (byte[])value2);
-         }
-         else
-         {
-            assertEquals(entry1.getValue(), value2);
-         }
-      }
-   }
-   
-   protected void checkListsEquivalent(List l1, List l2)
-   {      
-      Iterator iter1 = l1.iterator();
-      Iterator iter2 = l2.iterator();
-      while (iter1.hasNext())
-      {
-         Object o1 = iter1.next();
-         Object o2 = iter2.next();
-         
-         if (o1 instanceof byte[])
-         {
-            checkByteArraysEqual((byte[])o1, (byte[])o2);
-         }
-         else
-         {
-            assertEquals(o1, o2);
-         }
-      }
-   }
-   
-   public static class WibblishObject implements Serializable
-   {
-      private static final long serialVersionUID = -822739710811857027L;
-      public String wibble;
-      public WibblishObject()
-      {
-         this.wibble = new GUID().toString();
-      }
-      public boolean equals(Object other)
-      {
-         if (!(other instanceof WibblishObject))
-         {
-            return false;
-         }
-         WibblishObject oo = (WibblishObject)other;
-         return oo.wibble.equals(this.wibble);
-      }
-   }
-   
-   protected HashMap generateFilledMap(boolean useObject)
-   {
-      HashMap headers = new HashMap();
-      for (int j = 0; j < 27; j++)
-      {
-         //put some crap in the map
-         int k;
-         if (useObject)
-         {
-            k = j % 11;
-         }
-         else
-         {
-            k = j % 10;
-         }
-         
-         switch (k)
-         {
-            case 0:
-               headers.put(new GUID().toString(), randString(1000));
-            case 1:
-               headers.put(new GUID().toString(), randByte());
-            case 2:
-               headers.put(new GUID().toString(), randShort());
-            case 3:
-               headers.put(new GUID().toString(), randInt());
-            case 4:
-               headers.put(new GUID().toString(), randLong());
-            case 5:
-               headers.put(new GUID().toString(), randBool());
-            case 6:
-               headers.put(new GUID().toString(), randFloat());
-            case 7:
-               headers.put(new GUID().toString(), randDouble());
-            case 8:
-               headers.put(new GUID().toString(), randLong());
-            case 9:
-               headers.put(new GUID().toString(), randByteArray(500));
-            case 10:
-               headers.put(new GUID().toString(), new WibblishObject());               
-         }
-      }
-      return headers;
-   }
-   
-   protected Byte randByte()
-   {
-      return new Byte((byte)(Math.random() * (2^8 - 1) - (2^7)));
-   }
-   
-   protected Short randShort()
-   {
-      return new Short((short)(Math.random() * (2^16 - 1) - (2^15)));
-   }
-   
-   protected Integer randInt()
-   {
-      return new Integer((int)(Math.random() * (2^32 - 1) - (2^31)));
-   }
-   
-   protected Long randLong()
-   {
-      return new Long((long)(Math.random() * (2^64 - 1) - (2^64)));
-   }
-   
-   protected Boolean randBool()
-   {
-      return new Boolean(Math.random() > 0.5);
-   }
-   
-   protected Float randFloat()
-   {
-      return new Float((float)(Math.random() * 1000000));
-   }
-   
-   protected Double randDouble()
-   {
-      return new Double(Math.random() * 1000000);
-   }
-   
-   protected String randString(int length)
-   {
-      StringBuffer buf = new StringBuffer(length);
-      for (int i = 0; i < length; i++)
-      {
-         buf.append(randChar().charValue());
-      }
-      return buf.toString();
-   }
-   
-   protected byte[] randByteArray(int size)
-   {
-      String s = randString(size / 2);
-      return s.getBytes();
-   }
-   
-   protected Character randChar()
-   {
-      return new Character((char)randShort().shortValue());
-   }
-   
-   protected void checkByteArraysEqual(byte[] b1, byte[] b2)
-   {
-      if (b1 == null || b2 == null)
-      {
-         fail();
-      }
-      if (b1.length != b2.length)
-      {
-         fail();
-      }
-      
-      for (int i = 0; i < b1.length; i++)
-      {
-         assertEquals(b1[i], b2[i]);
-      }
-      
-   }
-   
-   protected class MockXid implements Xid
-   {
-      byte[] branchQual;
-      int formatID;
-      byte[] globalTxId;
-      
-      protected MockXid()
-      {
-         branchQual = new GUID().toString().getBytes();
-         formatID = randInt().intValue();
-         globalTxId = new GUID().toString().getBytes();
-      }
-
-      public byte[] getBranchQualifier()
-      {
-         return branchQual;
-      }
-
-      public int getFormatId()
-      {
-         return formatID;
-      }
-
-      public byte[] getGlobalTransactionId()
-      {
-         return globalTxId;
-      }
-      
-      public boolean equals(Object other)
-      {
-         if (!(other instanceof Xid))
-         {
-            return false;
-         }
-         Xid xother = (Xid)other;
-         if (xother.getFormatId() != this.formatID)
-         {
-            return false;
-         }
-         if (xother.getBranchQualifier().length != this.branchQual.length)
-         {
-            return false;
-         }
-         if (xother.getGlobalTransactionId().length != this.globalTxId.length)
-         {
-            return false;
-         }
-         for (int i = 0; i < this.branchQual.length; i++)
-         {
-            byte[] otherBQ = xother.getBranchQualifier();
-            if (this.branchQual[i] != otherBQ[i])
-            {
-               return false;
-            }
-         }
-         for (int i = 0; i < this.globalTxId.length; i++)
-         {
-            byte[] otherGtx = xother.getGlobalTransactionId();
-            if (this.globalTxId[i] != otherGtx[i])
-            {
-               return false;
-            }
-         }
-         return true;
-      }
-      
-   }
-   
-   protected void doTransactionCommit(boolean xa, boolean batch, boolean useBinaryStream, boolean trailingByte) throws Throwable
-   {
-      doSetup(batch, useBinaryStream, trailingByte, 100);
-
-      Channel channel = new SimpleChannel(0, ms);
-      
-      IDManager idm = new IDManager("TRANSACTION_ID", 10, pm);
-      idm.start();
-      
-      TransactionRepository txRep = new TransactionRepository(pm, ms, idm);
-      txRep.start();
-
-      log.debug("transaction log started");
-
-      Message[] messages = createMessages(10);
-      
-      Message m1 = messages[0];
-      Message m2 = messages[1];
-      Message m3 = messages[2];      
-      Message m4 = messages[3];
-      Message m5 = messages[4];
-
-      Transaction tx = null;
-      if (xa)
-      {         
-         tx = txRep.createTransaction(new MockXid());
-      }
-      else
-      {
-         tx = txRep.createTransaction();
-      }
-      
-      if (xa)
-      {
-    	  assertEquals(1,txRep.getNumberOfRegisteredTransactions());
-      }
-      else
-      {
-    	  assertEquals(0,txRep.getNumberOfRegisteredTransactions());
-      }
-      
-      MessageReference ref1 = ms.reference(m1);
-      MessageReference ref2 = ms.reference(m2);  
-      MessageReference ref3 = ms.reference(m3);       
-      MessageReference ref4 = ms.reference(m4);
-      MessageReference ref5 = ms.reference(m5);
-
-      log.debug("adding references non-transactionally");
-
-      // Add first two refs non transactionally
-      pm.addReference(channel.getChannelID(), ref1, null);
-      pm.addReference(channel.getChannelID(), ref2, null);
-      
-      //check they're there
-      List refs = getReferenceIds(channel.getChannelID());
-      assertNotNull(refs);
-      assertEquals(2, refs.size());
-      assertTrue(refs.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(refs.contains(new Long(ref2.getMessage().getMessageID())));
-      
-      List msgs = getMessageIds();
-      assertNotNull(msgs);
-      assertEquals(2, msgs.size());
-      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));
-
-      log.debug("ref1 and ref2 are there");
-
-      //Add the next 3 refs transactionally
-      pm.addReference(channel.getChannelID(), ref3, tx);
-      pm.addReference(channel.getChannelID(), ref4, tx);
-      pm.addReference(channel.getChannelID(), ref5, tx);
-      
-      //Remove the other 2 transactionally
-      pm.removeReference(channel.getChannelID(), ref1, tx);
-      pm.removeReference(channel.getChannelID(), ref2, tx);
-      
-      //Check the changes aren't visible
-      refs = getReferenceIds(channel.getChannelID());
-      assertNotNull(refs);
-      assertEquals(2, refs.size());
-      assertTrue(refs.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(refs.contains(new Long(ref2.getMessage().getMessageID())));  
-      
-      msgs = getMessageIds();
-      assertNotNull(msgs);
-      assertEquals(2, msgs.size());
-      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));
-      
-      //commit transaction
-      tx.commit();
-
-      assertEquals("numberOfRegisteredTransactions",0,txRep.getNumberOfRegisteredTransactions());
-      
-      //check we can see only the last 3 refs
-      refs = getReferenceIds(channel.getChannelID());
-      assertNotNull(refs);
-      assertEquals(3, refs.size()); 
-      assertTrue(refs.contains(new Long(ref3.getMessage().getMessageID())));
-      assertTrue(refs.contains(new Long(ref4.getMessage().getMessageID())));  
-      assertTrue(refs.contains(new Long(ref5.getMessage().getMessageID())));
-      
-      msgs = getMessageIds();
-      assertNotNull(msgs);
-      assertEquals(3, msgs.size());
-      assertTrue(msgs.contains(new Long(ref3.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref4.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref5.getMessage().getMessageID())));
-   }
-         
-   protected void doTransactionRollback(boolean xa, boolean batch, boolean useBinaryStream, boolean trailingByte) throws Throwable
-   {
-      doSetup(batch, useBinaryStream, trailingByte, 100);
-
-      Channel channel = new SimpleChannel(0, ms);
-      
-      IDManager idm = new IDManager("TRANSACTION_ID", 10, pm);
-      idm.start();
-      
-      TransactionRepository txRep = new TransactionRepository(pm, ms, idm);
-      txRep.start();
- 
-      Message[] messages = createMessages(10);     
-      
-      Message m1 = messages[0];
-      Message m2 = messages[1];
-      Message m3 = messages[2];      
-      Message m4 = messages[3];
-      Message m5 = messages[4];
-
-      
-      Transaction tx = null;
-      if (xa)
-      {
-         tx = txRep.createTransaction(new MockXid());
-      }
-      else
-      {
-         tx = txRep.createTransaction();
-      }
-      
-      MessageReference ref1 = ms.reference(m1);
-      MessageReference ref2 = ms.reference(m2);  
-      MessageReference ref3 = ms.reference(m3);       
-      MessageReference ref4 = ms.reference(m4);
-      MessageReference ref5 = ms.reference(m5);  
-
-      //Add first two refs non transactionally
-      pm.addReference(channel.getChannelID(), ref1, null);
-      pm.addReference(channel.getChannelID(), ref2, null);
-      
-      //check they're there
-      List refs = getReferenceIds(channel.getChannelID());
-      assertNotNull(refs);
-      assertEquals(2, refs.size());
-      assertTrue(refs.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(refs.contains(new Long(ref2.getMessage().getMessageID())));      
-      
-      List msgs = getMessageIds();
-      assertNotNull(msgs);
-      assertEquals(2, msgs.size());
-      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));
-      
-      
-      
-      //Add the next 3 refs transactionally
-      pm.addReference(channel.getChannelID(), ref3, tx);
-      pm.addReference(channel.getChannelID(), ref4, tx);
-      pm.addReference(channel.getChannelID(), ref5, tx);
-      
-      //Remove the other 2 transactionally
-      pm.removeReference(channel.getChannelID(), ref1, tx);
-      pm.removeReference(channel.getChannelID(), ref2, tx);
-      
-      //Check the changes aren't visible
-      refs = getReferenceIds(channel.getChannelID());
-      assertNotNull(refs);
-      assertEquals(2, refs.size());
-      assertTrue(refs.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(refs.contains(new Long(ref2.getMessage().getMessageID())));  
-      
-      msgs = getMessageIds();
-      assertNotNull(msgs);
-      assertEquals(2, msgs.size());
-      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));
-      
-      //rollback transaction
-      tx.rollback();
-      
-      refs = getReferenceIds(channel.getChannelID());
-      assertNotNull(refs);
-      assertEquals(2, refs.size());
-      assertTrue(refs.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(refs.contains(new Long(ref2.getMessage().getMessageID())));  
-      
-      msgs = getMessageIds();
-      assertNotNull(msgs);
-      assertEquals(2, msgs.size());
-      assertTrue(msgs.contains(new Long(ref1.getMessage().getMessageID())));
-      assertTrue(msgs.contains(new Long(ref2.getMessage().getMessageID())));          
-   }
-   
-   
-   protected List getReferenceIds(long channelId) throws Throwable
-   {
-      InitialContext ctx = new InitialContext();
-
-      TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
-      DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
-      
-      javax.transaction.Transaction txOld = mgr.suspend();
-      mgr.begin();
-
-      Connection conn = ds.getConnection();
-      String sql = "SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE CHANNEL_ID=? ORDER BY ORD";
-      PreparedStatement ps = conn.prepareStatement(sql);
-      ps.setLong(1, channelId);
-   
-      ResultSet rs = ps.executeQuery();
-      
-      List msgIds = new ArrayList();
-      
-      while (rs.next())
-      {
-         long msgId = rs.getLong(1);
-         msgIds.add(new Long(msgId));
-      }
-      rs.close();
-      ps.close();
-      conn.close();
-
-      mgr.commit();
-
-      if (txOld != null)
-      {
-         mgr.resume(txOld);
-      }
-      
-      return msgIds;
-   }
-   
-   protected List getMessageIds() throws Throwable
-   {
-      InitialContext ctx = new InitialContext();
-
-      TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
-      DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
-      
-      javax.transaction.Transaction txOld = mgr.suspend();
-      mgr.begin();
-
-      Connection conn = ds.getConnection();
-      String sql = "SELECT MESSAGE_ID FROM JBM_MSG ORDER BY MESSAGE_ID";
-      PreparedStatement ps = conn.prepareStatement(sql);
-      
-      ResultSet rs = ps.executeQuery();
-      
-      List msgIds = new ArrayList();
-      
-      while (rs.next())
-      {
-         long msgId = rs.getLong(1);
-         msgIds.add(new Long(msgId));
-      }
-      rs.close();
-      ps.close();
-      conn.close();
-
-      mgr.commit();
-
-      if (txOld != null)
-      {
-         mgr.resume(txOld);
-      }
-      
-      return msgIds;
-   }
-   
-}
-
-
-

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/SimpleMessageStoreTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/SimpleMessageStoreTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/SimpleMessageStoreTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.plugin;
-
-import org.jboss.test.messaging.core.plugin.base.MessageStoreTestBase;
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.message.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

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/base/MessageStoreTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/base/MessageStoreTestBase.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/base/MessageStoreTestBase.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,349 +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.base;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.test.messaging.tools.jmx.ServiceContainer;
-import org.jboss.test.messaging.util.CoreMessageFactory;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-
-
-/**
- * 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.
- *
- * @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 MessageStoreTestBase extends MessagingTestCase
-{
-   // Constants -----------------------------------------------------
-
-   public static final int NUMBER_OF_MESSAGES = 100;
-
-   // Static --------------------------------------------------------       
-
-   /**
-    * Makes sure the given reference refers the given message.
-    */
-   public static void assertCorrectReference(MessageReference ref, Message m)
-   {
-      assertEquals(m.getMessageID(), ref.getMessage().getMessageID());
-      assertEquals(m.isReliable(), ref.getMessage().isReliable());
-      assertEquals(m.getExpiration(), ref.getMessage().getExpiration());
-      assertEquals(m.getTimestamp(), ref.getMessage().getTimestamp());
-      assertEquals(m.getPriority(), ref.getMessage().getPriority());
-      assertEquals(0, ref.getDeliveryCount());
-
-      Map messageHeaders = m.getHeaders();
-      Map refHeaders = ref.getMessage().getHeaders();
-      assertEquals(messageHeaders.size(), refHeaders.size());
-
-      for(Iterator i = messageHeaders.keySet().iterator(); i.hasNext(); )
-      {
-         Object header = i.next();
-         Object value = messageHeaders.get(header);
-         assertTrue(refHeaders.containsKey(header));
-         assertEquals(value, refHeaders.get(header));
-      }
-   }
-
-   // Attributes ----------------------------------------------------
-
-   protected ServiceContainer sc;
-   protected MessageStore ms;
-
-   protected Map headers;
-
-   // Constructors --------------------------------------------------
-
-   public MessageStoreTestBase(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-
-      sc = new ServiceContainer("all,-remoting,-security");
-      sc.start();
-
-      headers = new HashMap();
-      headers.put("someKey", "someValue");
-   }
-
-   public void tearDown() throws Exception
-   {
-      headers.clear();
-      headers = null;
-      sc.stop();
-      sc = null;
-
-      super.tearDown();
-   }
-
-   ////
-   //// Non-reliable message
-   ////
-
-   //////
-   ////// One message
-   //////
-
-   ////////
-   //////// One strong reference
-   ////////
-
-   public void testMessageStore_1() throws Exception
-   {
-      Message m = CoreMessageFactory.
-      createCoreMessage(0, false, 777l, 888l, (byte)9, headers, "payload");
-
-      // recoverable store, non-reliable message, one message
-      MessageReference ref = ms.reference(m);
-      assertCorrectReference(ref, m);
-      ref.releaseMemoryReference();
-
-      ref = ms.reference(m.getMessageID());
-      assertNull(ref);
-   }
-
-   ////////
-   //////// Two strong references
-   ////////
-
-   public void testMessageStore_1_1() throws Exception
-   {
-
-      Message m = CoreMessageFactory.
-      createCoreMessage(0, false, 777l, 888l, (byte)9, headers, "payload");
-
-      // recoverable store, non-reliable message, one message
-      MessageReference ref = ms.reference(m);
-      assertCorrectReference(ref, m);
-
-      MessageReference ref2 = ms.reference(m);
-
-      assertCorrectReference(ref2, m);
-   }
-
-   //////
-   ////// Multiple messages
-   //////
-
-   public void testMessageStore_2() throws Exception
-   {
-      Message[] m = new Message[NUMBER_OF_MESSAGES];
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++ )
-      {
-         m[i] = CoreMessageFactory.createCoreMessage(i, false, 700 + i, 800 + i,
-                                             (byte)(i % 10), headers, "payload" + i);
-
-         // recoverable store, non-reliable message, one message
-         refs[i] = ms.reference(m[i]);
-         assertCorrectReference(refs[i], m[i]);
-      }
-
-      // get reachable reference
-
-      for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {         
-         assertCorrectReference(refs[i], m[i]);
-         refs[i].releaseMemoryReference();
-      }
-
-      for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         assertNull(ms.reference(m[i].getMessageID()));
-      }
-   }
-
-   ////
-   //// Reliable message
-   ////
-
-   //////
-   ////// One message
-   //////
-
-   ////////
-   //////// One strong reference
-   ////////
-
-   public void testMessageStore_3() throws Exception
-   {
-      Message m = CoreMessageFactory.
-      createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");
-
-      // recoverable store, non-reliable message, one message
-      MessageReference ref = ms.reference(m);
-      assertCorrectReference(ref, m);
-
-      ref.releaseMemoryReference();
-
-      // there's no strong reference to the unique message reference anymore, so the message store
-      // should be cleaned of everything that pertains to that message
-
-      ref = ms.reference(m.getMessageID());
-      assertNull(ref);
-   }
-
-   ////////
-   //////// Two strong references
-   ////////
-
-   public void testMessageStore_3_1() throws Exception
-   {
-      Message m = CoreMessageFactory.
-      createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");
-
-      // recoverable store, non-reliable message, one message
-      MessageReference ref = ms.reference(m);
-      assertCorrectReference(ref, m);
-
-      MessageReference ref2 = ms.reference(m);
-
-      assertCorrectReference(ref2, m);
-   }
-
-   //////
-   ////// Multiple messages
-   //////
-
-   public void testMessageStore_4() throws Exception
-   {
-      Message[] m = new Message[NUMBER_OF_MESSAGES];
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++ )
-      {
-         m[i] = CoreMessageFactory.createCoreMessage(i, true, 700 + i, 800 + i,
-                                             (byte)(i % 10), headers, "payload" + i);
-
-         // recoverable store, non-reliable message, one message
-         refs[i] = ms.reference(m[i]);
-         assertCorrectReference(refs[i], m[i]);
-      }
-
-      // get reachable reference
-
-      for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {         
-         refs[i].releaseMemoryReference();
-      }
-
-      // there are no strong references to the message reference anymore, so the message store
-      // should be cleaned of everything that pertains to those message
-
-      for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         assertNull(ms.reference(m[i].getMessageID()));
-      }
-   }
-   
-   public void testMessageStore_6() throws Exception
-   {
-
-      Message m = CoreMessageFactory.
-      createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");
-
-      // non-recoverable store, non-reliable message, one message
-      MessageReference ref = ms.reference(m);
-      assertCorrectReference(ref, m);
-      
-      //Create another reference from that reference
-      MessageReference ref2 = ms.reference(m);
-          
-      ref.releaseMemoryReference();
-      
-      MessageReference ref3 = ms.reference(m.getMessageID());
-      assertNotNull(ref3);
-      ref3.releaseMemoryReference();
-      
-      assertCorrectReference(ref3, m);
-      
-      ref2.releaseMemoryReference();
-
-      // there's no strong reference to the unique message reference anymore, so the message store
-      // should be cleaned of everything that pertains to that message
-
-      ref3 = ms.reference(m.getMessageID());
-      assertNull(ref3);
-   }
-   
-   public void testMessageStore_7() throws Exception
-   {
-      Message m = CoreMessageFactory.
-      createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");
-
-      // non-recoverable store, non-reliable message, one message
-      MessageReference ref = ms.reference(m);
-      assertCorrectReference(ref, m);
-      
-      MessageReference ref2 = ms.reference(ref.getMessage().getMessageID());
-      assertNotNull(ref2);      
-      assertCorrectReference(ref2, m);
-      
-      MessageReference ref3 = ms.reference(ref.getMessage().getMessageID());
-      assertNotNull(ref3);      
-      assertCorrectReference(ref3, m);
-      
-      ref.releaseMemoryReference();
-      ref2.releaseMemoryReference();
-      ref3.releaseMemoryReference();
-      
-      MessageReference ref4 = ms.reference(ref.getMessage().getMessageID());
-            
-      assertNull(ref4);                
-   }
-
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/base/PostOfficeTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/base/PostOfficeTestBase.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/base/PostOfficeTestBase.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,317 +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.base;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.jboss.messaging.core.FilterFactory;
-import org.jboss.messaging.core.Queue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.message.SimpleMessageStore;
-import org.jboss.messaging.core.plugin.IDManager;
-import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
-import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
-import org.jboss.messaging.core.plugin.contract.Condition;
-import org.jboss.messaging.core.plugin.contract.ConditionFactory;
-import org.jboss.messaging.core.plugin.contract.FailoverMapper;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.plugin.contract.PostOffice;
-import org.jboss.messaging.core.plugin.postoffice.DefaultPostOffice;
-import org.jboss.messaging.core.plugin.postoffice.cluster.ClusterRouterFactory;
-import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
-import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultFailoverMapper;
-import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultRouterFactory;
-import org.jboss.messaging.core.plugin.postoffice.cluster.MessagePullPolicy;
-import org.jboss.messaging.core.plugin.postoffice.cluster.NullMessagePullPolicy;
-import org.jboss.messaging.core.plugin.postoffice.cluster.RoundRobinRouterFactory;
-import org.jboss.messaging.core.plugin.postoffice.cluster.jchannelfactory.JChannelFactory;
-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.SimpleConditionFactory;
-import org.jboss.test.messaging.core.SimpleFilterFactory;
-import org.jboss.test.messaging.core.SimpleReceiver;
-import org.jboss.test.messaging.core.plugin.postoffice.cluster.ClusteredPersistenceServiceConfigFileJChannelFactory;
-import org.jboss.test.messaging.tools.ServerManagement;
-import org.jboss.test.messaging.tools.jmx.ServiceContainer;
-import org.jboss.test.messaging.util.CoreMessageFactory;
-
-/**
- * 
- * A PostOfficeTestBase
- *
- * @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$</tt>
- *
- * $Id$
- *
- */
-public class PostOfficeTestBase extends MessagingTestCase
-{
-   // Constants ------------------------------------------------------------------------------------
-
-   // Static ---------------------------------------------------------------------------------------
-
-   protected static ClusteredPostOffice createClusteredPostOffice(int nodeID,
-                                                                  String groupName,
-                                                                  ServiceContainer sc,
-                                                                  MessageStore ms,
-                                                                  PersistenceManager pm,
-                                                                  TransactionRepository tr)
-      throws Exception
-   {
-      return createClusteredPostOffice(nodeID, groupName, 5000, 5000, new NullMessagePullPolicy(),
-                                       sc, ms, pm, tr, new DefaultRouterFactory());
-   }
-   
-   protected static ClusteredPostOffice createClusteredPostOfficeWithRRR(int nodeID,
-            String groupName,
-            ServiceContainer sc,
-            MessageStore ms,
-            PersistenceManager pm,
-            TransactionRepository tr)
-       throws Exception
-   {
-      return createClusteredPostOffice(nodeID, groupName, 5000, 5000, new NullMessagePullPolicy(),
-               sc, ms, pm, tr, new RoundRobinRouterFactory());
-   }
-   
-   protected static ClusteredPostOffice createClusteredPostOffice(int nodeID,
-            String groupName,
-            long stateTimeout,
-            long castTimeout,
-            MessagePullPolicy pullPolicy,
-            ServiceContainer sc,
-            MessageStore ms,
-            PersistenceManager pm,
-            TransactionRepository tr) throws Exception
-   {
-      return createClusteredPostOffice(nodeID, groupName, stateTimeout, castTimeout, pullPolicy, sc, ms, pm, tr,
-            new DefaultRouterFactory());
-   }
-   
-
-   protected static ClusteredPostOffice createClusteredPostOffice(int nodeID,
-                                                                  String groupName,
-                                                                  long stateTimeout,
-                                                                  long castTimeout,
-                                                                  MessagePullPolicy pullPolicy,
-                                                                  ServiceContainer sc,
-                                                                  MessageStore ms,
-                                                                  PersistenceManager pm,
-                                                                  TransactionRepository tr,
-                                                                  ClusterRouterFactory rf)
-      throws Exception
-   {
-      FilterFactory ff = new SimpleFilterFactory();
-      FailoverMapper mapper = new DefaultFailoverMapper();
-      ConditionFactory cf = new SimpleConditionFactory();
-
-      // we're testing with priority JGroups stack configurations we're shipping with the release
-
-      String configFilePath = sc.getPersistenceConfigFile(true);
-
-      // TODO (ovidiu) we're temporarily ignoring the multiplex option, it doesn't work well
-      boolean ignoreMultiplexer = true;
-      JChannelFactory jChannelFactory =
-         new ClusteredPersistenceServiceConfigFileJChannelFactory(configFilePath,
-                                                                  ignoreMultiplexer,
-                                                                  sc.getMBeanServer());
-
-      DefaultClusteredPostOffice postOffice =
-         new DefaultClusteredPostOffice(sc.getDataSource(), sc.getTransactionManager(),
-                                        sc.getClusteredPostOfficeSQLProperties(), true, nodeID,
-                                        "Clustered", ms, pm, tr, ff, cf,
-                                        groupName, jChannelFactory,
-                                        stateTimeout, castTimeout, pullPolicy, rf, mapper, 1000, 10);
-      
-      postOffice.start();
-
-      return postOffice;
-   }
-
-   // Attributes -----------------------------------------------------------------------------------
-
-   protected ServiceContainer sc;
-
-   protected IDManager channelIDManager;
-   
-   protected IDManager transactionIDManager;
-   
-   protected PersistenceManager pm;
-      
-   protected MessageStore ms;
-   
-   protected TransactionRepository tr;
-   
-   protected ConditionFactory conditionFactory;
-   
-   // Constructors --------------------------------------------------
-
-   public PostOfficeTestBase(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-   
-   protected PostOffice createPostOffice() throws Exception
-   {
-      FilterFactory ff = new SimpleFilterFactory();
-      
-      ConditionFactory cf= new SimpleConditionFactory();
-      
-      DefaultPostOffice postOffice = 
-         new DefaultPostOffice(sc.getDataSource(), sc.getTransactionManager(),
-                               sc.getPostOfficeSQLProperties(), true, 1, "Simple", ms, pm, tr, ff, cf);
-      
-      postOffice.start();      
-      
-      return postOffice;
-   }
-   
-   
-   
-   private static long msgCount;
-   
-   protected List sendMessages(String conditionText, boolean persistent, PostOffice office, int num, Transaction tx) throws Exception
-   {
-      List list = new ArrayList();
-      
-      for (int i = 0; i < num; i++)
-      {         
-         Message msg = CoreMessageFactory.createCoreMessage(msgCount++, persistent, null);      
-         
-         MessageReference ref = ms.reference(msg);         
-         
-         Condition condition = conditionFactory.createCondition(conditionText);
-         
-         boolean routed = office.route(ref, condition, null);         
-         
-         assertTrue(routed);
-         
-         list.add(msg);
-      }
-      
-      Thread.sleep(1000);
-      
-      return list;
-   }
-   
-   protected void checkContainsAndAcknowledge(Message msg, SimpleReceiver receiver, Queue queue) throws Throwable
-   {
-      List msgs = receiver.getMessages();
-      assertNotNull(msgs);
-      assertEquals(1, msgs.size());
-      Message msgRec = (Message)msgs.get(0);
-      assertEquals(msg.getMessageID(), msgRec.getMessageID());
-      receiver.acknowledge(msgRec, null);
-      msgs = queue.browse();
-      assertNotNull(msgs);
-      assertTrue(msgs.isEmpty()); 
-      receiver.clear();
-   }
-   
-   protected void checkContainsAndAcknowledge(List msgList, SimpleReceiver receiver, Queue queue) throws Throwable
-   {
-      List msgs = receiver.getMessages();
-      assertNotNull(msgs);
-      assertEquals(msgList.size(), msgs.size());
-      
-      for (int i = 0; i < msgList.size(); i++)
-      {
-         Message msgRec = (Message)msgs.get(i);
-         Message msgCheck = (Message)msgList.get(i);
-         assertEquals(msgCheck.getMessageID(), msgRec.getMessageID());
-         receiver.acknowledge(msgRec, null);
-      }
-      
-      msgs = queue.browse();
-      assertNotNull(msgs);
-      assertTrue(msgs.isEmpty()); 
-      receiver.clear();
-   }
-   
-   protected void checkEmpty(SimpleReceiver receiver) throws Throwable
-   {
-      List msgs = receiver.getMessages();
-      assertNotNull(msgs);
-      assertTrue(msgs.isEmpty());
-   }
-
-   protected void setUp() throws Exception
-   {
-      super.setUp();
-
-      sc = new ServiceContainer("all");
-
-      sc.start();
-
-      pm =
-         new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager(),
-                  sc.getPersistenceManagerSQLProperties(),
-                  true, true, true, false, 100);
-      pm.start();
-
-      transactionIDManager = new IDManager("TRANSACTION_ID", 10, pm);
-      transactionIDManager.start();
-
-      ms = new SimpleMessageStore();
-      ms.start();
-
-      tr = new TransactionRepository(pm, ms, transactionIDManager);
-      tr.start();
-
-      channelIDManager = new IDManager("CHANNEL_ID", 10, pm);
-      channelIDManager.start();
-
-      conditionFactory = new SimpleConditionFactory();
-
-      log.debug("setup done");
-   }
-
-   protected void tearDown() throws Exception
-   {
-      if (!ServerManagement.isRemote())
-      {
-         sc.stop();
-         sc = null;
-      }
-      pm.stop();
-      tr.stop();
-      ms.stop();
-      transactionIDManager.stop();
-      channelIDManager.stop();
-
-      super.tearDown();
-   }
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-}
-
-

Copied: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/ClusteredPersistenceServiceConfigFileJChannelFactory.java (from rev 2781, trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/ClusteredPersistenceServiceConfigFileJChannelFactory.java)
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/ClusteredPersistenceServiceConfigFileJChannelFactory.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/ClusteredPersistenceServiceConfigFileJChannelFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,194 @@
+/**
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.test.messaging.core.plugin.postoffice;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.contract.JChannelFactory;
+import org.jboss.messaging.core.impl.jchannelfactory.MultiplexerJChannelFactory;
+import org.jboss.messaging.util.XMLUtil;
+import org.jboss.test.messaging.tools.jboss.MBeanConfigurationElement;
+import org.jboss.test.messaging.tools.jboss.ServiceDeploymentDescriptor;
+import org.jboss.test.messaging.tools.jmx.ServiceConfigHelper;
+import org.jgroups.JChannel;
+import org.w3c.dom.Element;
+
+/**
+ * A JChannelFactory that reads the configuration of its synchronous/asynchronous JChannels from a
+ * Messaging-style clustered persistence service configuration file (usually shipped with a
+ * Messaging installation). The idea is to test with priority whatever we ship.
+ *
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ */
+public class ClusteredPersistenceServiceConfigFileJChannelFactory implements JChannelFactory
+{
+   // Constants ------------------------------------------------------------------------------------
+
+   public static final Logger log =
+      Logger.getLogger(ClusteredPersistenceServiceConfigFileJChannelFactory.class);
+
+   // Static ---------------------------------------------------------------------------------------
+
+   // Attributes -----------------------------------------------------------------------------------
+
+   private String configFilePath;
+
+   // we're either using a delegate MultiplexerJChannelFactory, if we find one configured in the
+   // file ...
+   private JChannelFactory multiplexorDelegate;
+
+   // ... or just plain XML configuration.
+   private Element syncConfig;
+   private Element asyncConfig;
+
+   // Constructors ---------------------------------------------------------------------------------
+
+   /**
+    * @param configFilePath - the configuration file to read JGroups stack configurations from. Must
+    *        be relative to classpath components in order to be found.
+    * @param skipMultiplex - if true, ignore multiplex option, even if a channel factory name is
+    *        found in the configuration file. Otherwise, the channel factory will take priority
+    *        if found.
+    * @param mbeanServer - the MBeanServer instance, needed in case a channel factory name is found
+    *        in the configuration file. In this situation, the channel factory is preferred.
+    *        Irrelevant if skipMultiplex is true.
+    */
+   public ClusteredPersistenceServiceConfigFileJChannelFactory(String configFilePath,
+                                                               boolean skipMultiplex,
+                                                               MBeanServer mbeanServer)
+      throws Exception
+   {
+      this.configFilePath = configFilePath;
+      init(configFilePath, skipMultiplex, mbeanServer);
+   }
+
+   // JChannelFactory ------------------------------------------------------------------------------
+
+   public JChannel createSyncChannel() throws Exception
+   {
+      if (multiplexorDelegate != null)
+      {
+         return multiplexorDelegate.createSyncChannel();
+      }
+      else
+      {
+         return new JChannel(syncConfig);
+      }
+   }
+
+   public JChannel createASyncChannel() throws Exception
+   {
+      if (multiplexorDelegate != null)
+      {
+         return multiplexorDelegate.createASyncChannel();
+      }
+      else
+      {
+         return new JChannel(asyncConfig);
+      }
+   }
+
+   // Public ---------------------------------------------------------------------------------------
+
+   public String toString()
+   {
+      return "ClusteredPersistenceServiceConfigFileJChannelFactory[" + configFilePath + "]";
+   }
+
+   // Package protected ----------------------------------------------------------------------------
+
+   // Protected ------------------------------------------------------------------------------------
+
+   // Private --------------------------------------------------------------------------------------
+
+   private void init(String configFilePath, boolean skipMultiplex, MBeanServer mbeanServer)
+      throws Exception
+   {
+      log.debug("using configuration file " + configFilePath);
+
+      MBeanConfigurationElement postOfficeConfig =
+         ServiceConfigHelper.loadServiceConfiguration(configFilePath, "PostOffice");
+
+      // first, we try to use a channel factory service, if we find one configured
+      String s = (String)postOfficeConfig.getAttributeValue("ChannelFactoryName");
+
+      if (s != null && !skipMultiplex)
+      {
+         // there's a chance we can use a multiplexer service
+         ObjectName channelFactoryName = new ObjectName(s);
+
+         String channelPartitionName =
+            (String)postOfficeConfig.getAttributeValue("ChannelPartitionName");
+
+         if (channelPartitionName == null)
+         {
+            throw new IllegalStateException("Cannot find ChannelPartitionName");
+         }
+
+         String syncChannelName = (String)postOfficeConfig.getAttributeValue("SyncChannelName");
+
+         if (syncChannelName == null)
+         {
+            throw new IllegalStateException("Cannot find SyncChannelName");
+         }
+
+         String asyncChannelName = (String)postOfficeConfig.getAttributeValue("AsyncChannelName");
+
+         if (asyncChannelName == null)
+         {
+            throw new IllegalStateException("Cannot find AsyncChannelName");
+         }
+
+         try
+         {
+            if(mbeanServer.getMBeanInfo(channelFactoryName) != null)
+            {
+               multiplexorDelegate =
+                  new MultiplexerJChannelFactory(mbeanServer, channelFactoryName,
+                                                 channelPartitionName, syncChannelName,
+                                                 asyncChannelName);
+
+               // initialization ends here, we've found what we were looking for
+               return;
+            }
+         }
+         catch (Exception e)
+         {
+            // that's alright, no multiplexer there, use the regular XML configuration
+            log.debug("Wasn't able to find " + s);
+         }
+      }
+
+      // the only chance now is to use the XML configurations
+
+      s = (String)postOfficeConfig.getAttributeValue("SyncChannelConfig");
+
+      if (s == null)
+      {
+         throw new IllegalStateException("Cannot find SyncChannelConfig");
+      }
+
+      syncConfig = XMLUtil.stringToElement(s);
+
+      s = (String)postOfficeConfig.getAttributeValue("AsyncChannelConfig");
+
+      if (s == null)
+      {
+         throw new IllegalStateException("Cannot find AsyncChannelConfig");
+      }
+
+      asyncConfig = XMLUtil.stringToElement(s);
+   }
+
+   // Inner classes --------------------------------------------------------------------------------
+
+}

Added: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/ClusteredPostOfficeTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/ClusteredPostOfficeTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/ClusteredPostOfficeTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,2639 @@
+/*
+  * 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.postoffice;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.messaging.core.contract.Binding;
+import org.jboss.messaging.core.contract.Condition;
+import org.jboss.messaging.core.contract.PostOffice;
+import org.jboss.messaging.core.contract.Queue;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.test.messaging.core.PostOfficeTestBase;
+import org.jboss.test.messaging.core.SimpleCondition;
+
+/**
+ * 
+ * A DefaultClusteredPostOfficeTest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 2386 $</tt>
+ *
+ * $Id: DefaultPostOfficeTest.java 2386 2007-02-21 18:07:44Z timfox $
+ *
+ */
+public class ClusteredPostOfficeTest extends PostOfficeTestBase
+{
+   // Constants ------------------------------------------------------------------------------------
+
+   // Static ---------------------------------------------------------------------------------------
+   
+   // Attributes -----------------------------------------------------------------------------------
+    
+   // Constructors ---------------------------------------------------------------------------------
+
+   public ClusteredPostOfficeTest(String name)
+   {
+      super(name);
+   }
+
+   // Public ---------------------------------------------------------------------------------------
+
+   public final void testSimpleJoinLeave() throws Throwable
+   {
+      PostOffice office1 = null;
+      PostOffice office2 = null;
+      PostOffice office3 = null;
+      
+      try
+      {         
+         office1 = createClusteredPostOffice(1, "testgroup");
+
+         office2 = createClusteredPostOffice(2, "testgroup");
+                  
+         office3 = createClusteredPostOffice(3, "testgroup");
+         
+         Thread.sleep(2000);
+         
+         Set nodes = office1.nodeIDView();         
+         assertTrue(nodes.contains(new Integer(1)));
+         assertTrue(nodes.contains(new Integer(2)));
+         assertTrue(nodes.contains(new Integer(3)));
+         
+         nodes = office2.nodeIDView();         
+         assertTrue(nodes.contains(new Integer(1)));
+         assertTrue(nodes.contains(new Integer(2)));
+         assertTrue(nodes.contains(new Integer(3)));
+         
+         nodes = office3.nodeIDView();         
+         assertTrue(nodes.contains(new Integer(1)));
+         assertTrue(nodes.contains(new Integer(2)));
+         assertTrue(nodes.contains(new Integer(3)));
+         
+         office1.stop();
+         office1 = null;
+         
+         office2.stop();
+         office2 = null;
+         
+         office3.stop();
+         office3 = null;
+      }
+      finally
+      {
+         if (office1 != null)
+         {
+            office1.stop();
+         }
+         
+         if (office2 != null)
+         {
+            office2.stop();
+         }
+         
+         if (office3 != null)
+         {
+            office3.stop();
+         }         
+      }
+         
+   }
+   
+   public final void testGetFailoverMap() throws Throwable
+   {
+      PostOffice office1 = null;
+      PostOffice office2 = null;
+      PostOffice office3 = null;
+      
+      try
+      {         
+         office1 = createClusteredPostOffice(1, "testgroup");
+
+         office2 = createClusteredPostOffice(2, "testgroup");
+                  
+         office3 = createClusteredPostOffice(3, "testgroup");
+         
+         Thread.sleep(2000);
+         
+         Map failoverMap1 = office1.getFailoverMap();
+         
+         Map failoverMap2 = office2.getFailoverMap();
+         
+         Map failoverMap3 = office3.getFailoverMap();
+         
+         assertEquals(failoverMap1, failoverMap2);
+         
+         assertEquals(failoverMap2, failoverMap3);
+         
+         office1.stop();
+         office1 = null;
+         
+         office2.stop();
+         office2 = null;
+         
+         office3.stop();
+         office3 = null;
+      }
+      finally
+      {
+         if (office1 != null)
+         {
+            office1.stop();
+         }
+         
+         if (office2 != null)
+         {
+            office2.stop();
+         }
+         
+         if (office3 != null)
+         {
+            office3.stop();
+         }         
+      }
+         
+   }
+   
+   public final void testClusteredBindUnbind() throws Throwable
+   {
+      PostOffice office1 = null;
+      PostOffice office2 = null;
+      PostOffice office3 = null;
+      
+      try
+      {         
+         // Start one office
+         
+         office1 = createClusteredPostOffice(1, "testgroup");
+         
+         log.info("Created office1");
+         
+         // Add a couple of queues
+         
+         Queue queue1 = new MessagingQueue(1, "sub1", channelIDManager.getID(), ms, pm, false, -1, null, true, false);
+         queue1.activate();
+
+         Condition condition1 = new SimpleCondition("topic1");
+         
+         office1.addBinding(new Binding(condition1, queue1), false);
+         
+         log.info("Added binding1");
+         
+         Queue queue2 = new MessagingQueue(1, "sub2", channelIDManager.getID(), ms, pm, false, -1, null, true, false);
+         queue2.activate();
+
+         office1.addBinding(new Binding(condition1, queue2), false);
+         
+         log.info("Added binding2");
+         
+         // Start another office - make sure it picks up the bindings from the first node
+         
+         office2 = createClusteredPostOffice(2, "testgroup");
+         
+         log.info("Created office 2");
+         
+         // Should return all queues
+         Collection queues = office2.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(2, queues.size());
+         assertTrue(queues.contains(queue1));
+         assertTrue(queues.contains(queue2));
+                
+         
+         // Add another queue on node 2
+         
+         Queue queue3 = new MessagingQueue(2, "sub3", channelIDManager.getID(), ms, pm, false, -1, null, true, false);
+         queue3.activate();
+
+         office2.addBinding(new Binding(condition1, queue3), false);
+  
+         // Make sure both nodes pick it up
+         
+         queues = office1.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(3, queues.size());
+         assertTrue(queues.contains(queue1));
+         assertTrue(queues.contains(queue2));
+         assertTrue(queues.contains(queue3));
+         
+         queues = office2.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(3, queues.size());
+         assertTrue(queues.contains(queue1));
+         assertTrue(queues.contains(queue2));
+         assertTrue(queues.contains(queue3));
+        
+
+         // Add another binding on node 2
+         
+         Queue queue4 = new MessagingQueue(2, "sub4", channelIDManager.getID(), ms, pm, false, -1, null, true, false);
+         queue4.activate();
+
+         office2.addBinding(new Binding(condition1, queue4), false);
+         
+         // Make sure both nodes pick it up
+         
+         queues = office1.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(4, queues.size());
+         assertTrue(queues.contains(queue1));
+         assertTrue(queues.contains(queue2));
+         assertTrue(queues.contains(queue3));
+         assertTrue(queues.contains(queue4));
+         
+         queues = office2.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(4, queues.size());
+         assertTrue(queues.contains(queue1));
+         assertTrue(queues.contains(queue2));
+         assertTrue(queues.contains(queue3));
+         assertTrue(queues.contains(queue4));
+         
+         // Unbind binding 1 and binding 2
+         office1.removeBinding(queue1.getName(), false);
+         
+         office1.removeBinding(queue2.getName(), false);
+         
+         // Make sure bindings are not longer available on either node
+         
+         queues = office1.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(2, queues.size());
+         assertTrue(queues.contains(queue3));
+         assertTrue(queues.contains(queue4));
+         
+         queues = office2.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(2, queues.size());
+         assertTrue(queues.contains(queue3));
+         assertTrue(queues.contains(queue4));
+         
+         
+         // Add a third office
+                  
+         office3 = createClusteredPostOffice(3, "testgroup");
+         
+         // Maks sure it picks up the bindings
+         
+         queues = office3.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(2, queues.size());
+         assertTrue(queues.contains(queue3));
+         assertTrue(queues.contains(queue4));
+         
+         // Add another binding on node 3
+                  
+         Queue queue5 = new MessagingQueue(3, "sub5", channelIDManager.getID(), ms, pm, false, -1, null, true, false);
+         queue5.activate();
+         
+         office3.addBinding(new Binding(condition1, queue5), false);
+         
+         // Make sure all nodes pick it up
+         
+         queues = office1.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(3, queues.size());
+         assertTrue(queues.contains(queue3));
+         assertTrue(queues.contains(queue4));
+         assertTrue(queues.contains(queue5));
+         
+         queues = office2.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(3, queues.size());
+         assertTrue(queues.contains(queue3));
+         assertTrue(queues.contains(queue4));
+         assertTrue(queues.contains(queue5));
+         
+         queues = office3.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(3, queues.size());
+         assertTrue(queues.contains(queue3));
+         assertTrue(queues.contains(queue4));
+         assertTrue(queues.contains(queue5));
+         
+         // Add a durable and a non durable binding on node 1
+         
+         Queue queue6 = new MessagingQueue(1, "sub6", channelIDManager.getID(), ms, pm, true, -1, null, true, false);
+         queue6.activate();
+         
+         office1.addBinding(new Binding(condition1, queue6), false);
+         
+         Queue queue7 = new MessagingQueue(1, "sub7", channelIDManager.getID(), ms, pm, false, -1, null, true, false);
+         queue7.activate();
+         
+         office1.addBinding(new Binding(condition1, queue7), false);
+         
+         
+         // Make sure all nodes pick them up
+         
+         queues = office1.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(5, queues.size());
+         assertTrue(queues.contains(queue3));
+         assertTrue(queues.contains(queue4));
+         assertTrue(queues.contains(queue5));
+         assertTrue(queues.contains(queue6));
+         assertTrue(queues.contains(queue7));
+         
+         queues = office2.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(5, queues.size());
+         assertTrue(queues.contains(queue3));
+         assertTrue(queues.contains(queue4));
+         assertTrue(queues.contains(queue5));
+         assertTrue(queues.contains(queue6));
+         assertTrue(queues.contains(queue7));
+         
+         queues = office3.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(5, queues.size());
+         assertTrue(queues.contains(queue3));
+         assertTrue(queues.contains(queue4));
+         assertTrue(queues.contains(queue5));
+         assertTrue(queues.contains(queue6));
+         assertTrue(queues.contains(queue7));
+               
+         log.info("****** stopping office1");
+         // Stop office 1
+         office1.stop();
+  
+         // Need to sleep since it may take some time for the view changed request to reach the
+         // members which causes the bindings to be removed.
+         
+         Thread.sleep(1000);
+         
+         // All it's bindings should be removed from the other nodes, including durable
+         
+         queues = office2.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(3, queues.size());
+         assertTrue(queues.contains(queue3));
+         assertTrue(queues.contains(queue4));
+         assertTrue(queues.contains(queue5));
+         
+         queues = office3.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(3, queues.size());
+         assertTrue(queues.contains(queue3));
+         assertTrue(queues.contains(queue4));
+         assertTrue(queues.contains(queue5));
+         
+         // Stop office 2
+         office2.stop();
+         
+         queues = office3.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(1, queues.size());
+         assertTrue(queues.contains(queue5));
+         
+         // Restart office 1 and office 2
+         office1 = createClusteredPostOffice(1, "testgroup");
+         
+         office2 = createClusteredPostOffice(2, "testgroup");
+                  
+         queues = office1.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(2, queues.size());
+         assertTrue(queues.contains(queue5));
+         assertTrue(queues.contains(queue6));
+         
+         queues = office2.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(2, queues.size());
+         assertTrue(queues.contains(queue5));
+         assertTrue(queues.contains(queue6));
+         
+         queues = office3.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(2, queues.size());
+         assertTrue(queues.contains(queue5));
+         assertTrue(queues.contains(queue6));
+
+         // Stop all offices
+         
+         office1.stop();
+         office2.stop();
+         office3.stop();
+         
+         // Start them all
+         office1 = createClusteredPostOffice(1, "testgroup");
+         office2 = createClusteredPostOffice(2, "testgroup");
+         office3 = createClusteredPostOffice(3, "testgroup");
+         
+         // Only the durable queue should survive
+         
+         queues = office1.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(1, queues.size());
+         assertTrue(queues.contains(queue6));
+         
+         queues = office2.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(1, queues.size());
+         assertTrue(queues.contains(queue6));
+         
+         queues = office3.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(1, queues.size());
+         assertTrue(queues.contains(queue6));       
+         
+         //Unbind it
+         
+         office1.removeBinding(queue6.getName(), false);
+         
+         queues = office1.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertTrue(queues.isEmpty());
+         
+         queues = office2.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertTrue(queues.isEmpty());
+         
+         queues = office3.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertTrue(queues.isEmpty());     
+         
+         
+         //Bind another few more clustered
+                           
+         Queue queue8 = new MessagingQueue(1, "sub8", channelIDManager.getID(), ms, pm, false, -1, null, true, false);
+         queue8.activate();
+         
+         Queue queue9 = new MessagingQueue(2, "sub9", channelIDManager.getID(), ms, pm, false, -1, null, true, false);
+         queue9.activate();
+         
+         Queue queue10 = new MessagingQueue(2, "sub10", channelIDManager.getID(), ms, pm, false, -1, null, true, false);
+         queue10.activate();
+         
+         //Bind on different conditions
+         
+         office1.addBinding(new Binding(condition1, queue8), false);
+         
+         office2.addBinding(new Binding(condition1, queue9), false);
+         
+         Condition condition2 = new SimpleCondition("topic2");
+         
+         office2.addBinding(new Binding(condition2, queue10), false);
+         
+         queues = office1.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(2, queues.size());
+         assertTrue(queues.contains(queue8));
+         assertTrue(queues.contains(queue9));
+         
+         queues = office2.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(2, queues.size());
+         assertTrue(queues.contains(queue8));
+         assertTrue(queues.contains(queue9));
+         
+         queues = office3.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(2, queues.size());
+         assertTrue(queues.contains(queue8));
+         assertTrue(queues.contains(queue9));
+         
+         //Now a couple of non clustered queues
+         
+         Queue queue11 = new MessagingQueue(1, "sub11", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue11.activate();
+         
+         Queue queue12 = new MessagingQueue(2, "sub12", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue12.activate();
+         
+         office1.addBinding(new Binding(condition1, queue11), false);
+         
+         office2.addBinding(new Binding(condition1, queue12), false);
+         
+         queues = office1.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(3, queues.size());
+         assertTrue(queues.contains(queue8));
+         assertTrue(queues.contains(queue9));
+         assertTrue(queues.contains(queue11));
+         
+         queues = office2.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(3, queues.size());
+         assertTrue(queues.contains(queue8));
+         assertTrue(queues.contains(queue9));
+         assertTrue(queues.contains(queue12));
+         
+         queues = office3.getQueuesForCondition(condition1, false);
+         assertNotNull(queues);
+         assertEquals(2, queues.size());
+         assertTrue(queues.contains(queue8));
+         assertTrue(queues.contains(queue9));                   
+      }
+      finally
+      {
+         if (office1 != null)
+         {
+            office1.stop();
+         }
+         
+         if (office2 != null)
+         {
+            office2.stop();
+         }
+         
+         if (office3 != null)
+         {
+            office3.stop();
+         }
+         
+         if (checkNoBindingData())
+         {
+            fail("data still in database");
+         }
+      }
+   }
+   
+   
+
+   public final void testClusteredBindUnbindAll() throws Throwable
+   {
+      PostOffice office1 = null;
+      PostOffice office2 = null;
+      PostOffice office3 = null;
+      
+      try
+      {         
+         // Start one office
+         
+      	log.info("Creating office1");
+      	
+         office1 = createClusteredPostOffice(1, "testgroup");
+         
+         log.info("Created office1");
+                
+         Queue queue1 = new MessagingQueue(1, "sub1", channelIDManager.getID(), ms, pm, false, -1, null, true, false);
+         queue1.activate();
+         
+         Condition condition1 = new SimpleCondition("condition1");         
+         
+         office1.addBinding(new Binding(condition1, queue1), true);
+         
+         Collection queues = office1.getQueuesForCondition(condition1, false);
+                  
+         assertNotNull(queues);
+         
+         assertEquals(1, queues.size());
+         
+         assertTrue(queues.contains(queue1));
+         
+         // Start another office -
+         
+         log.info("creating office2");
+         office2 = createClusteredPostOffice(2, "testgroup");   
+         log.info("created office2");
+         
+         
+         Queue queue2 = new MessagingQueue(2, "sub2", channelIDManager.getID(), ms, pm, false, -1, null, true, false);
+         queue2.activate();
+         
+         office2.addBinding(new Binding(condition1, queue2), true);
+         
+         queues = office1.getQueuesForCondition(condition1, false);
+         
+         assertNotNull(queues);
+         
+         assertEquals(4, queues.size());
+         
+         assertTrue(queues.contains(queue1));
+         assertTrue(queues.contains(queue2));
+         Iterator iter = queues.iterator();
+         
+         // TODO - when a new node joins the cluster it has to locally bind any queues previously bodun with all on other nodes.
+         
+         while (iter.hasNext())
+         {
+         	Queue queue = (Queue)iter.next();
+         	
+         	if (!queue.equals(queue1) && !queue.equals(queue2))
+         	{
+         		if (queue.getName().equals("sub1"))
+         		{
+         			assertEquals(2, queue.getNodeID());
+         		}
+         		else if (queue.getName().equals("sub2"))
+         		{
+         			assertEquals(1, queue.getNodeID());
+         		}
+         		else
+         		{
+         			fail("Invalid queue name " + queue.getName());
+         		}
+         	}
+         }
+         
+         queues = office2.getQueuesForCondition(condition1, false);
+         
+         assertNotNull(queues);
+         
+         assertEquals(4, queues.size());
+         
+         assertTrue(queues.contains(queue1));
+         assertTrue(queues.contains(queue2));
+         iter = queues.iterator();
+         
+         // TODO - when a new node joins the cluster it has to locally bind any queues previously bodun with all on other nodes.
+         
+         while (iter.hasNext())
+         {
+         	Queue queue = (Queue)iter.next();
+         	
+         	if (!queue.equals(queue1) && !queue.equals(queue2))
+         	{
+         		if (queue.getName().equals("sub1"))
+         		{
+         			assertEquals(1, queue.getNodeID());
+         		}
+         		else if (queue.getName().equals("sub2"))
+         		{
+         			assertEquals(2, queue.getNodeID());
+         		}
+         		else
+         		{
+         			fail("Invalid queue name " + queue.getName());
+         		}
+         	}
+         }
+         
+         
+         office2.removeBinding("sub2", true);
+         
+         queues = office1.getQueuesForCondition(condition1, false);
+         
+         assertNotNull(queues);
+         
+         assertEquals(2, queues.size());
+         
+         assertTrue(queues.contains(queue1));
+         iter = queues.iterator();
+         
+
+         while (iter.hasNext())
+         {
+         	Queue queue = (Queue)iter.next();
+         	
+         	if (!queue.equals(queue1))
+         	{
+         		if (queue.getName().equals("sub1"))
+         		{
+         			assertEquals(2, queue.getNodeID());
+         		}         		
+         		else
+         		{
+         			fail("Invalid queue name " + queue.getName());
+         		}
+         	}
+         }
+         
+         queues = office2.getQueuesForCondition(condition1, false);
+         
+         assertNotNull(queues);
+         
+         assertEquals(2, queues.size());
+         
+         assertTrue(queues.contains(queue1));
+         iter = queues.iterator();
+         
+
+         while (iter.hasNext())
+         {
+         	Queue queue = (Queue)iter.next();
+         	
+         	if (!queue.equals(queue1))
+         	{
+         		if (queue.getName().equals("sub1"))
+         		{
+         			assertEquals(1, queue.getNodeID());
+         		}         		
+         		else
+         		{
+         			fail("Invalid queue name " + queue.getName());
+         		}
+         	}
+         }
+         
+         office2.removeBinding("sub1", true);
+         
+         queues = office2.getQueuesForCondition(condition1, false);
+         
+         assertNotNull(queues);
+         
+         assertTrue(queues.isEmpty());                
+      }
+      finally
+      {
+         if (office1 != null)
+         {
+            office1.stop();
+         }
+         
+         if (office2 != null)
+         {
+            office2.stop();
+         }
+         
+         if (office3 != null)
+         {
+            office3.stop();
+         }
+         
+         if (checkNoBindingData())
+         {
+            fail("data still in database");
+         }
+      }
+   }
+//   
+//   public final void testClusteredRoutePersistent() throws Throwable
+//   {
+//      clusteredRoute(true);
+//   }
+//   
+//   public final void testClusteredRouteNonPersistent() throws Throwable
+//   {
+//      clusteredRoute(false);
+//   }
+//   
+//   public final void testClusteredTransactionalRoutePersistent() throws Throwable
+//   {
+//      clusteredTransactionalRoute(true);
+//   }
+//   
+//   public final void testClusteredTransactionalRouteNonPersistent() throws Throwable
+//   {
+//      clusteredTransactionalRoute(false);
+//   }
+//   
+//   public void testClusteredNonPersistentRouteWithFilterNonRecoverable() throws Throwable
+//   {
+//      this.clusteredRouteWithFilter(false, false);
+//   }
+//   
+//   public void testClusteredPersistentRouteWithFilterNonRecoverable() throws Throwable
+//   {
+//      this.clusteredRouteWithFilter(true, false);
+//   }
+//   
+//   public void testClusteredNonPersistentRouteWithFilterRecoverable() throws Throwable
+//   {
+//      this.clusteredRouteWithFilter(false, true);
+//   }
+//   
+//   public void testClusteredPersistentRouteWithFilterRecoverable() throws Throwable
+//   {
+//      this.clusteredRouteWithFilter(true, true);
+//   }
+//      
+//   public void testRouteSharedPointToPointQueuePersistentNonRecoverable() throws Throwable
+//   {
+//      this.routeSharedQueue(true, false);
+//   }
+//   
+//   public void testRouteSharedPointToPointQueueNonPersistentNonRecoverable() throws Throwable
+//   {
+//      this.routeSharedQueue(false, false);
+//   }
+//   
+//   public void testRouteSharedPointToPointQueuePersistentRecoverable() throws Throwable
+//   {
+//      this.routeSharedQueue(true, true);
+//   }
+//   
+//   public void testRouteSharedPointToPointQueueNonPersistentRecoverable() throws Throwable
+//   {
+//      this.routeSharedQueue(false, true);
+//   }
+//   
+//   public void testRouteComplexTopicPersistent() throws Throwable
+//   {
+//      this.routeComplexTopic(true);
+//   }
+//   
+//   public void testRouteComplexTopicNonPersistent() throws Throwable
+//   {
+//      this.routeComplexTopic(false);
+//   }
+//         
+//   public void testRouteLocalQueuesPersistentNonRecoverable() throws Throwable
+//   {
+//      this.routeLocalQueues(true, false);
+//   }
+//   
+//   public void testRouteLocalQueuesNonPersistentNonRecoverable() throws Throwable
+//   {
+//      this.routeLocalQueues(false, false);
+//   }
+//   
+//   public void testRouteLocalQueuesPersistentRecoverable() throws Throwable
+//   {
+//      this.routeLocalQueues(true, true);
+//   }
+//   
+//   public void testRouteLocalQueuesNonPersistentRecoverable() throws Throwable
+//   {
+//      this.routeLocalQueues(false, true);
+//   }
+   
+   
+   /*
+    * We should allow the clustered bind of queues with the same queue name on different nodes of the
+    * cluster
+    */
+   public void testBindSameName() throws Throwable
+   {
+      PostOffice office1 = null;
+      
+      PostOffice office2 = null;
+          
+      try
+      {   
+         office1 = createClusteredPostOffice(1, "testgroup");
+         
+         office2 = createClusteredPostOffice(2, "testgroup");
+         
+         Queue queue1 = new MessagingQueue(1, "queue1", channelIDManager.getID(), ms, pm, false, -1, null, true, false);
+         queue1.activate();
+         
+         Condition condition1 = new SimpleCondition("queue1");
+         
+         office1.addBinding(new Binding(condition1, queue1), false);
+
+         Queue queue2 = new MessagingQueue(2, "queue1", channelIDManager.getID(), ms, pm, false, -1, null, true, false);
+         queue2.activate();
+
+         office2.addBinding(new Binding(condition1, queue2), false);
+
+         Queue queue3 = new MessagingQueue(1, "queue1", channelIDManager.getID(), ms, pm, false, -1, null, true, false);
+         queue3.activate();
+         
+         try
+         {
+            office1.addBinding(new Binding(condition1, queue3), false);
+            fail();
+         }
+         catch (Exception e)
+         {
+            //Ok
+         }
+
+         Queue queue4 =  new MessagingQueue(2, "queue1", channelIDManager.getID(), ms, pm, false, -1, null, true, false);
+         queue4.activate();
+         
+         try
+         {
+            office2.addBinding(new Binding(condition1, queue4), false);
+            fail();
+         }
+         catch (Exception e)
+         {
+            //Ok
+         }
+         
+         office1.removeBinding(queue1.getName(), false);
+
+         office2.removeBinding(queue2.getName(), false);                
+      }
+      finally
+      {
+         if (office1 != null)
+         {            
+            office1.stop();
+         }
+         
+         if (office2 != null)
+         {
+            office2.stop();
+         }
+      }
+   }
+ 
+   // Package protected ----------------------------------------------------------------------------
+
+   // Protected ------------------------------------------------------------------------------------
+//   
+//   protected void clusteredRouteWithFilter(boolean persistentMessage, boolean recoverable)
+//      throws Throwable
+//   {
+//      PostOffice office1 = null;
+//      
+//      PostOffice office2 = null;
+//          
+//      try
+//      {   
+//         office1 = createPostOffice(1, "testgroup", sc, ms, pm, tr);
+//         office2 = createPostOffice(2, "testgroup", sc, ms, pm, tr);
+//         
+//         SimpleFilter filter1 = new SimpleFilter(2);
+//         SimpleFilter filter2 = new SimpleFilter(3);
+//      
+//         LocalClusteredQueue queue1 =
+//            new LocalClusteredQueue(1, "queue1", channelIDManager.getID(), ms, pm,
+//                                    true, recoverable, -1, filter1);
+//
+//         office1.bindQueue(new SimpleCondition("topic1"), queue1);
+//         
+//         LocalClusteredQueue queue2 =
+//            new LocalClusteredQueue(2, "queue2", channelIDManager.getID(), ms, pm,
+//                                    true, recoverable, -1, filter2);
+//
+//         office2.bindQueue(new SimpleCondition("topic1"), queue2);
+//         
+//         LocalClusteredQueue queue3 =
+//            new LocalClusteredQueue(2, "queue3", channelIDManager.getID(), ms, pm, true,
+//                                    recoverable, -1, null);
+//
+//         office2.bindQueue(new SimpleCondition("topic1"), queue3);
+//         
+//         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//
+//         queue1.add(receiver1);
+//
+//         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//
+//         queue2.add(receiver2);
+//
+//         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//
+//         queue3.add(receiver3);
+//         
+//         Message msg1 = CoreMessageFactory.createCoreMessage(1);      
+//         MessageReference ref1 = ms.reference(msg1);  
+//         boolean routed = office1.route(ref1, new SimpleCondition("topic1"), null);   
+//         assertTrue(routed);
+//         
+//         
+//         Message msg2 = CoreMessageFactory.createCoreMessage(2);      
+//         MessageReference ref2 = ms.reference(msg2);         
+//         routed = office1.route(ref2, new SimpleCondition("topic1"), null);      
+//         assertTrue(routed);
+//         
+//         Message msg3 = CoreMessageFactory.createCoreMessage(3);      
+//         MessageReference ref3 = ms.reference(msg3);         
+//         routed = office1.route(ref3, new SimpleCondition("topic1"), null);      
+//         assertTrue(routed);
+//         
+//         Thread.sleep(2000);
+//         
+//         List msgs = receiver1.getMessages();
+//         assertNotNull(msgs);
+//         assertEquals(1, msgs.size());
+//         Message msgRec = (Message)msgs.get(0);
+//         assertTrue(msg2 == msgRec);
+//         receiver1.acknowledge(msgRec, null);
+//         msgs = queue1.browse();
+//         assertNotNull(msgs);
+//         assertTrue(msgs.isEmpty());  
+//         
+//         msgs = receiver2.getMessages();
+//         assertNotNull(msgs);
+//         assertEquals(1, msgs.size());
+//         msgRec = (Message)msgs.get(0);
+//         assertTrue(msg3 == msgRec);
+//         receiver2.acknowledge(msgRec, null);
+//         msgs = queue2.browse();
+//         assertNotNull(msgs);
+//         assertTrue(msgs.isEmpty());  
+//         
+//         msgs = receiver3.getMessages();
+//         assertNotNull(msgs);
+//         assertEquals(3, msgs.size());
+//         Message msgRec1 = (Message)msgs.get(0);
+//         assertTrue(msg1 == msgRec1);
+//         Message msgRec2 = (Message)msgs.get(1);
+//         assertTrue(msg2 == msgRec2);
+//         Message msgRec3 = (Message)msgs.get(2);
+//         assertTrue(msg3 == msgRec3);
+//          
+//         receiver3.acknowledge(msgRec1, null);
+//         receiver3.acknowledge(msgRec2, null);
+//         receiver3.acknowledge(msgRec3, null);
+//         msgs = queue3.browse();
+//         assertNotNull(msgs);
+//         assertTrue(msgs.isEmpty()); 
+//                  
+//         if (checkNoMessageData())
+//         {
+//            fail("Message data still in database");
+//         }
+//      }
+//      finally
+//      {
+//         if (office1 != null)
+//         {
+//            office1.stop();
+//         }
+//         
+//         if (office2 != null)
+//         {
+//            office2.stop();
+//         }
+//         
+//      }
+//   }
+//   
+//   protected void clusteredRoute(boolean persistentMessage) throws Throwable
+//   {
+//      PostOffice office1 = null;
+//      
+//      PostOffice office2 = null;
+//          
+//      try
+//      {   
+//         office1 = createPostOffice(1, "testgroup", sc, ms, pm, tr);
+//         office2 = createPostOffice(2, "testgroup", sc, ms, pm, tr);
+//      
+//         //Two topics with a mixture of durable and non durable subscriptions
+//         
+//         LocalClusteredQueue[] queues = new LocalClusteredQueue[16];
+//         Binding[] bindings = new Binding[16];
+//         
+//         queues[0] = new LocalClusteredQueue(1, "sub1", channelIDManager.getID(), ms, pm, true, false, -1, null);
+//         bindings[0] = office1.bindQueue(new SimpleCondition("topic1"), queues[0]);
+//         
+//         queues[1] = new LocalClusteredQueue(1, "sub2", channelIDManager.getID(), ms, pm, true, false, -1, null);
+//         bindings[1] = office1.bindQueue(new SimpleCondition("topic1"), queues[1]);
+//         
+//         queues[2] = new LocalClusteredQueue(2, "sub3", channelIDManager.getID(), ms, pm, true, false, -1, null);
+//         bindings[2] = office2.bindQueue(new SimpleCondition("topic1"), queues[2]);
+//         
+//         queues[3] = new LocalClusteredQueue(2, "sub4", channelIDManager.getID(), ms, pm, true, false, -1, null);
+//         bindings[3] = office2.bindQueue(new SimpleCondition("topic1"), queues[3]);
+//         
+//         queues[4] = new LocalClusteredQueue(2, "sub5", channelIDManager.getID(), ms, pm, true, true, -1, null);
+//         bindings[4] = office2.bindQueue(new SimpleCondition("topic1"), queues[4]);
+//         
+//         queues[5] = new LocalClusteredQueue(1, "sub6", channelIDManager.getID(), ms, pm, true, false, -1, null);
+//         bindings[5] = office1.bindQueue(new SimpleCondition("topic1"), queues[5]);
+//         
+//         queues[6] = new LocalClusteredQueue(1, "sub7", channelIDManager.getID(), ms, pm, true, true, -1, null);
+//         bindings[6] = office1.bindQueue(new SimpleCondition("topic1"), queues[6]);
+//         
+//         queues[7] = new LocalClusteredQueue(1, "sub8", channelIDManager.getID(), ms, pm, true, true, -1, null);
+//         bindings[7] = office1.bindQueue(new SimpleCondition("topic1"), queues[7]);
+//         
+//         queues[8] = new LocalClusteredQueue(1, "sub9", channelIDManager.getID(), ms, pm, true, false, -1, null);
+//         bindings[8] = office1.bindQueue(new SimpleCondition("topic2"), queues[8]);
+//         
+//         queues[9] = new LocalClusteredQueue(1, "sub10", channelIDManager.getID(), ms, pm, true, false, -1, null);
+//         bindings[9] = office1.bindQueue(new SimpleCondition("topic2"), queues[9]);
+//         
+//         queues[10] = new LocalClusteredQueue(2, "sub11", channelIDManager.getID(), ms, pm, true, false, -1, null);
+//         bindings[10] = office2.bindQueue(new SimpleCondition("topic2"), queues[10]);
+//         
+//         queues[11] = new LocalClusteredQueue(2, "sub12", channelIDManager.getID(), ms, pm, true, false, -1, null);
+//         bindings[11] = office2.bindQueue(new SimpleCondition("topic2"), queues[11]);
+//         
+//         queues[12] = new LocalClusteredQueue(2, "sub13", channelIDManager.getID(), ms, pm, true, true, -1, null);
+//         bindings[12] = office2.bindQueue(new SimpleCondition("topic2"), queues[12]);
+//         
+//         queues[13] = new LocalClusteredQueue(1, "sub14", channelIDManager.getID(), ms, pm, true, false, -1, null);
+//         bindings[13] = office1.bindQueue(new SimpleCondition("topic2"), queues[13]);
+//         
+//         queues[14] = new LocalClusteredQueue(1, "sub15", channelIDManager.getID(), ms, pm, true, true, -1, null);
+//         bindings[14] = office1.bindQueue(new SimpleCondition("topic2"), queues[14]);
+//         
+//         queues[15] = new LocalClusteredQueue(1, "sub16", channelIDManager.getID(), ms, pm, true, true, -1, null);
+//         bindings[15] = office1.bindQueue(new SimpleCondition("topic2"), queues[15]);
+//       
+//         SimpleReceiver[] receivers = new SimpleReceiver[16];
+//         
+//         for (int i = 0; i < 16; i++)
+//         {
+//            receivers[i] = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//            queues[i].add(receivers[i]);
+//         }
+//         
+//         Message msg = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
+//         MessageReference ref = ms.reference(msg);         
+//
+//         boolean routed = office1.route(ref, new SimpleCondition("topic1"), null);         
+//         assertTrue(routed);
+//         
+//         //Messages are sent asych so may take some finite time to arrive
+//         Thread.sleep(1000);
+//         
+//         for (int i = 0; i < 8; i++)
+//         {         
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertEquals(1, msgs.size());
+//            Message msgRec = (Message)msgs.get(0);
+//            assertEquals(msg.getMessageID(), msgRec.getMessageID());
+//            receivers[i].acknowledge(msgRec, null);
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty()); 
+//            receivers[i].clear();
+//         }
+//         
+//         for (int i = 8; i < 16; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//                  
+//         //Now route to topic2
+//         
+//         msg = CoreMessageFactory.createCoreMessage(2, persistentMessage, null);;      
+//         ref = ms.reference(msg);         
+//
+//         routed = office1.route(ref, new SimpleCondition("topic2"), null);         
+//         assertTrue(routed);
+//         //Messages are sent asych so may take some finite time to arrive
+//         Thread.sleep(1000);
+//         
+//         for (int i = 0; i < 8; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         for (int i = 8; i < 16; i++)
+//         {         
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertEquals(1, msgs.size());
+//            Message msgRec = (Message)msgs.get(0);
+//            assertEquals(msg.getMessageID(), msgRec.getMessageID());
+//            receivers[i].acknowledge(msgRec, null);
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty()); 
+//            receivers[i].clear();
+//         }
+//         
+//         if (checkNoMessageData())
+//         {
+//            fail("Message data still in database");
+//         }
+//
+//      }
+//      finally
+//      {
+//         if (office1 != null)
+//         {
+//            try
+//            {              
+//               office1.unbindQueue("sub7");
+//               office1.unbindQueue("sub8");               
+//               office1.unbindQueue("sub15");
+//               office1.unbindQueue("sub16");
+//            }
+//            catch (Exception ignore)
+//            {
+//               ignore.printStackTrace();
+//            }
+//            
+//            office1.stop();
+//         }
+//         
+//         if (office2 != null)
+//         {
+//            try
+//            {
+//               office2.unbindQueue("sub5");
+//               office2.unbindQueue("sub13");
+//            }
+//            catch (Exception ignore)
+//            {     
+//               ignore.printStackTrace();
+//            }
+//            office2.stop();
+//         }
+//        
+//      }
+//   }
+//   
+//   protected void routeSharedQueue(boolean persistentMessage, boolean recoverable) throws Throwable
+//   {
+//      PostOffice office1 = null;
+//      
+//      PostOffice office2 = null;
+//      
+//      PostOffice office3 = null;
+//      
+//      PostOffice office4 = null;
+//      
+//      PostOffice office5 = null;
+//      
+//      PostOffice office6 = null;
+//        
+//      try
+//      {   
+//         office1 = createPostOffice(1, "testgroup", sc, ms, pm, tr);
+//         office2 = createPostOffice(2, "testgroup", sc, ms, pm, tr);
+//         office3 = createPostOffice(3, "testgroup", sc, ms, pm, tr);
+//         office4 = createPostOffice(4, "testgroup", sc, ms, pm, tr);
+//         office5 = createPostOffice(5, "testgroup", sc, ms, pm, tr);
+//         office6 = createPostOffice(6, "testgroup", sc, ms, pm, tr);
+//    
+//         // We deploy the queue on nodes 1, 2, 3, 4 and 5
+//         // We don't deploy on node 6
+//         
+//         LocalClusteredQueue queue1 =
+//            new LocalClusteredQueue(1, "queue1", channelIDManager.getID(), ms, pm, true,
+//                                    recoverable, -1, null);
+//
+//         office1.bindQueue(new SimpleCondition("queue1"), queue1);
+//
+//         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         queue1.add(receiver1);
+//         
+//         LocalClusteredQueue queue2 =
+//            new LocalClusteredQueue(2, "queue1", channelIDManager.getID(), ms, pm, true,
+//                                    recoverable, -1, null);
+//
+//         office2.bindQueue(new SimpleCondition("queue1"), queue2);
+//
+//         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         queue2.add(receiver2);
+//         
+//         LocalClusteredQueue queue3 =
+//            new LocalClusteredQueue(3, "queue1", channelIDManager.getID(), ms, pm, true,
+//                                    recoverable, -1, null);
+//
+//         office3.bindQueue(new SimpleCondition("queue1"), queue3);
+//
+//         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         queue3.add(receiver3);
+//         
+//         LocalClusteredQueue queue4 =
+//            new LocalClusteredQueue(4, "queue1", channelIDManager.getID(), ms, pm,
+//                                    true, recoverable, -1, null);
+//
+//         office4.bindQueue(new SimpleCondition("queue1"), queue4);
+//
+//         SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         queue4.add(receiver4);
+//         
+//         LocalClusteredQueue queue5 =
+//            new LocalClusteredQueue(5, "queue1", channelIDManager.getID(), ms, pm, true,
+//                                    recoverable, -1, null);
+//
+//         office5.bindQueue(new SimpleCondition("queue1"), queue5);
+//         SimpleReceiver receiver5 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         queue5.add(receiver5);
+//        
+//         // We are using a AlwaysLocalRoutingPolicy so only the local queue should ever get the
+//         // message if the filter matches
+//                          
+//         Message msg = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
+//         MessageReference ref = ms.reference(msg);         
+//         boolean routed = office1.route(ref, new SimpleCondition("queue1"), null);         
+//         assertTrue(routed);
+//         checkContainsAndAcknowledge(msg, receiver1, queue1);
+//         this.checkEmpty(receiver2);
+//         this.checkEmpty(receiver3);
+//         this.checkEmpty(receiver4);
+//         this.checkEmpty(receiver5);
+//         
+//         msg = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
+//         ref = ms.reference(msg);         
+//         routed = office2.route(ref, new SimpleCondition("queue1"), null);         
+//         assertTrue(routed);
+//         this.checkEmpty(receiver1);
+//         checkContainsAndAcknowledge(msg, receiver2, queue2);
+//         this.checkEmpty(receiver3);
+//         this.checkEmpty(receiver4);
+//         this.checkEmpty(receiver5);
+//         
+//         msg = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
+//         ref = ms.reference(msg);         
+//         routed = office3.route(ref, new SimpleCondition("queue1"), null);         
+//         assertTrue(routed);
+//         this.checkEmpty(receiver1);
+//         this.checkEmpty(receiver2);
+//         checkContainsAndAcknowledge(msg, receiver3, queue3);
+//         this.checkEmpty(receiver4);
+//         this.checkEmpty(receiver5);
+//         
+//         msg = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
+//         ref = ms.reference(msg);         
+//         routed = office4.route(ref, new SimpleCondition("queue1"), null);         
+//         assertTrue(routed);
+//         this.checkEmpty(receiver1);
+//         this.checkEmpty(receiver2);
+//         this.checkEmpty(receiver3);
+//         checkContainsAndAcknowledge(msg, receiver4, queue3);
+//         this.checkEmpty(receiver5);
+//         
+//         msg = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
+//         ref = ms.reference(msg);         
+//         routed = office5.route(ref, new SimpleCondition("queue1"), null);         
+//         assertTrue(routed);
+//         this.checkEmpty(receiver1);
+//         this.checkEmpty(receiver2);         
+//         this.checkEmpty(receiver3);
+//         this.checkEmpty(receiver4);
+//         checkContainsAndAcknowledge(msg, receiver5, queue5);
+//         
+//         msg = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
+//         ref = ms.reference(msg);         
+//         routed = office6.route(ref, new SimpleCondition("queue1"), null);         
+//         assertTrue(routed);
+//         
+//         //The actual queue that receives the mesage is determined by the routing policy
+//         //The default uses round robin for the nodes (this is tested more thoroughly in
+//         //its own test)
+//         
+//         Thread.sleep(1000);
+//         
+//         checkContainsAndAcknowledge(msg, receiver1, queue1);
+//         this.checkEmpty(receiver1);
+//         this.checkEmpty(receiver2);         
+//         this.checkEmpty(receiver3);
+//         this.checkEmpty(receiver4);
+//         this.checkEmpty(receiver5);
+//                 
+//      }
+//      finally
+//      {
+//         if (office1 != null)
+//         {            
+//            office1.stop();
+//         }
+//         
+//         if (office2 != null)
+//         {
+//            office2.stop();
+//         }
+//         
+//         if (office3 != null)
+//         {            
+//            office3.stop();
+//         }
+//         
+//         if (office4 != null)
+//         {
+//            office4.stop();
+//         }
+//         
+//         if (office5 != null)
+//         {            
+//            office5.stop();
+//         }
+//         
+//         if (office6 != null)
+//         {            
+//            office6.stop();
+//         }
+//         
+//         if (checkNoMessageData())
+//         {
+//            fail("Message data still in database");
+//         }
+//      }
+//   }
+//   
+//
+//   /**
+//    * Clustered post offices should be able to have local queues bound to them too.
+//    */
+//   protected void routeLocalQueues(boolean persistentMessage, boolean recoverable) throws Throwable
+//   {
+//      PostOffice office1 = null;
+//      PostOffice office2 = null;
+//      PostOffice office3 = null;
+//                    
+//      try
+//      {   
+//         office1 = createPostOffice(1, "testgroup", sc, ms, pm, tr);
+//         office2 = createPostOffice(2, "testgroup", sc, ms, pm, tr);
+//         office3 = createPostOffice(3, "testgroup", sc, ms, pm, tr);
+//
+//         LocalClusteredQueue sub1 =
+//            new LocalClusteredQueue(1, "sub1", channelIDManager.getID(), ms, pm, true,
+//                                    recoverable, -1, null);
+//
+//         office1.bindQueue(new SimpleCondition("topic"), sub1);
+//
+//         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         sub1.add(receiver1);
+//         
+//         LocalClusteredQueue sub2 =
+//            new LocalClusteredQueue(2, "sub2", channelIDManager.getID(), ms, pm, true,
+//                                    recoverable, -1, null);
+//
+//         office2.bindQueue(new SimpleCondition("topic"), sub2);
+//         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         sub2.add(receiver2);
+//         
+//         LocalClusteredQueue sub3 =
+//            new LocalClusteredQueue(3, "sub3", channelIDManager.getID(), ms, pm, true,
+//                                    recoverable, -1, null);
+//
+//         office3.bindQueue(new SimpleCondition("topic"), sub3);
+//         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         sub3.add(receiver3);
+//         
+//         //Only the local sub should get it since we have bound locally
+//         
+//         Message msg = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
+//         MessageReference ref = ms.reference(msg);         
+//         boolean routed = office1.route(ref, new SimpleCondition("topic"), null);         
+//         assertTrue(routed);         
+//         Thread.sleep(500);         
+//         checkContainsAndAcknowledge(msg, receiver1, sub1);
+//         this.checkEmpty(receiver2);
+//         this.checkEmpty(receiver3);
+//         
+//         msg = CoreMessageFactory.createCoreMessage(2, persistentMessage, null);      
+//         ref = ms.reference(msg);         
+//         routed = office2.route(ref, new SimpleCondition("topic"), null);         
+//         assertTrue(routed);                  
+//         Thread.sleep(500);
+//         this.checkEmpty(receiver1);
+//         checkContainsAndAcknowledge(msg, receiver2, sub2);
+//         this.checkEmpty(receiver3);
+//         
+//         msg = CoreMessageFactory.createCoreMessage(3, persistentMessage, null);      
+//         ref = ms.reference(msg);         
+//         routed = office3.route(ref, new SimpleCondition("topic"), null);           
+//         assertTrue(routed);         
+//         Thread.sleep(500);
+//         this.checkEmpty(receiver1);         
+//         this.checkEmpty(receiver2);
+//         checkContainsAndAcknowledge(msg, receiver3, sub2);           
+//                         
+//         if (checkNoMessageData())
+//         {
+//            fail("Message data still in database");
+//         }
+//         
+//      }
+//      finally
+//      {
+//         if (office1 != null)
+//         {            
+//            office1.stop();
+//         }
+//         
+//         if (office2 != null)
+//         {
+//            office2.stop();
+//         }
+//         
+//         if (office3 != null)
+//         {            
+//            office3.stop();
+//         }
+//         
+//      }
+//   }
+//   
+//   
+//   
+//   /**
+//    * We set up a complex scenario with multiple subscriptions, shared and unshared on different
+//    * nodes.
+//    * 
+//    * node1: no subscriptions
+//    * node2: 2 non durable
+//    * node3: 1 non shared durable, 1 non durable
+//    * node4: 1 shared durable (shared1), 1 non shared durable, 3 non durable
+//    * node5: 2 shared durable (shared1 and shared2)
+//    * node6: 1 shared durable (shared2), 1 non durable
+//    * node7: 1 shared durable (shared2)
+//    * 
+//    * Then we send mess
+//    */
+//   protected void routeComplexTopic(boolean persistent) throws Throwable
+//   {
+//      PostOffice office1 = null;
+//      PostOffice office2 = null;
+//      PostOffice office3 = null;
+//      PostOffice office4 = null;
+//      PostOffice office5 = null;
+//      PostOffice office6 = null;
+//      PostOffice office7 = null;
+//        
+//      try
+//      {   
+//         office1 = createPostOffice(1, "testgroup", sc, ms, pm, tr);
+//         office2 = createPostOffice(2, "testgroup", sc, ms, pm, tr);
+//         office3 = createPostOffice(3, "testgroup", sc, ms, pm, tr);
+//         office4 = createPostOffice(4, "testgroup", sc, ms, pm, tr);
+//         office5 = createPostOffice(5, "testgroup", sc, ms, pm, tr);
+//         office6 = createPostOffice(6, "testgroup", sc, ms, pm, tr);
+//         office7 = createPostOffice(7, "testgroup", sc, ms, pm, tr);
+//         
+//         //Node 2
+//         //======
+//         
+//         // Non durable 1 on node 2
+//         LocalClusteredQueue nonDurable1 =
+//            new LocalClusteredQueue(2, "nondurable1", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//
+//         office2.bindQueue(new SimpleCondition("topic"), nonDurable1);
+//         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         nonDurable1.add(receiver1);
+//         
+//         // Non durable 2 on node 2
+//         LocalClusteredQueue nonDurable2 =
+//            new LocalClusteredQueue(2, "nondurable2", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//
+//         office2.bindQueue(new SimpleCondition("topic"), nonDurable2);
+//         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         nonDurable2.add(receiver2);
+//         
+//         //Node 3
+//         //======
+//         
+//         // Non shared durable
+//         LocalClusteredQueue nonSharedDurable1 =
+//            new LocalClusteredQueue(3, "nonshareddurable1", channelIDManager.getID(), ms,
+//                                    pm, true, true, -1, null);
+//
+//         office3.bindQueue(new SimpleCondition("topic"), nonSharedDurable1);
+//         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         nonSharedDurable1.add(receiver3);
+//         
+//         // Non durable
+//         LocalClusteredQueue nonDurable3 =
+//            new LocalClusteredQueue(3, "nondurable3", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//
+//         office3.bindQueue(new SimpleCondition("topic"), nonDurable3);
+//         SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         nonDurable3.add(receiver4);
+//         
+//         //Node 4
+//         //======
+//         
+//         // Shared durable
+//         LocalClusteredQueue sharedDurable1 =
+//            new LocalClusteredQueue(4, "shareddurable1", channelIDManager.getID(), ms, pm,
+//                                    true, true, -1, null);
+//
+//         office4.bindQueue(new SimpleCondition("topic"), sharedDurable1);
+//         SimpleReceiver receiver5 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         sharedDurable1.add(receiver5);
+//         
+//         // Non shared durable
+//         LocalClusteredQueue nonSharedDurable2 =
+//            new LocalClusteredQueue(4, "nonshareddurable2", channelIDManager.getID(), ms,
+//                                    pm, true, true, -1, null);
+//
+//         office4.bindQueue(new SimpleCondition("topic"), nonSharedDurable2);
+//         SimpleReceiver receiver6 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         nonSharedDurable2.add(receiver6);
+//         
+//         // Non durable
+//         LocalClusteredQueue nonDurable4 =
+//            new LocalClusteredQueue(4, "nondurable4", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//
+//         office4.bindQueue(new SimpleCondition("topic"), nonDurable4);
+//         SimpleReceiver receiver7 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         nonDurable4.add(receiver7);
+//         
+//         // Non durable
+//         LocalClusteredQueue nonDurable5 =
+//            new LocalClusteredQueue(4, "nondurable5", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         office4.bindQueue(new SimpleCondition("topic"), nonDurable5);
+//         SimpleReceiver receiver8 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         nonDurable5.add(receiver8);
+//         
+//         // Non durable
+//         LocalClusteredQueue nonDurable6 =
+//            new LocalClusteredQueue(4, "nondurable6", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         office4.bindQueue(new SimpleCondition("topic"), nonDurable6);
+//         SimpleReceiver receiver9 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         nonDurable6.add(receiver9);
+//         
+//         // Node 5
+//         //=======
+//         // Shared durable
+//         LocalClusteredQueue sharedDurable2 =
+//            new LocalClusteredQueue(5, "shareddurable1", channelIDManager.getID(), ms, pm,
+//                                    true, true, -1, null);
+//
+//         office5.bindQueue(new SimpleCondition("topic"), sharedDurable2);
+//         SimpleReceiver receiver10 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         sharedDurable2.add(receiver10);
+//         
+//         // Shared durable
+//         LocalClusteredQueue sharedDurable3 =
+//            new LocalClusteredQueue(5, "shareddurable2", channelIDManager.getID(), ms, pm,
+//                                    true, true, -1, null);
+//
+//         office5.bindQueue(new SimpleCondition("topic"), sharedDurable3);
+//         SimpleReceiver receiver11 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         sharedDurable3.add(receiver11);
+//         
+//         // Node 6
+//         //=========
+//         LocalClusteredQueue sharedDurable4 =
+//            new LocalClusteredQueue(6, "shareddurable2", channelIDManager.getID(), ms, pm,
+//                                    true, true, -1, null);
+//
+//         office6.bindQueue(new SimpleCondition("topic"), sharedDurable4);
+//         SimpleReceiver receiver12 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         sharedDurable4.add(receiver12);
+//         
+//         LocalClusteredQueue nonDurable7 =
+//            new LocalClusteredQueue(6, "nondurable7", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         office6.bindQueue(new SimpleCondition("topic"), nonDurable7);
+//         SimpleReceiver receiver13 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         nonDurable7.add(receiver13);
+//         
+//         //Node 7
+//         //=======
+//         LocalClusteredQueue sharedDurable5 =
+//            new LocalClusteredQueue(7, "shareddurable2", channelIDManager.getID(), ms, pm,
+//                                    true, true, -1, null);
+//
+//         office7.bindQueue(new SimpleCondition("topic"), sharedDurable5);
+//         SimpleReceiver receiver14 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         sharedDurable5.add(receiver14);
+//         
+//         
+//         //Send 1 message at node1
+//         //========================
+//         
+//         List msgs = sendMessages("topic", persistent, null, 1, null);
+//         
+//         //n2
+//         checkContainsAndAcknowledge(msgs, receiver1, nonDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver2, nonDurable2);
+//         
+//         //n3
+//         checkContainsAndAcknowledge(msgs, receiver3, nonSharedDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver4, nonDurable3);
+//         
+//         //n4
+//         checkContainsAndAcknowledge(msgs, receiver5, sharedDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver6, nonSharedDurable2);
+//         checkContainsAndAcknowledge(msgs, receiver7, nonDurable4);
+//         checkContainsAndAcknowledge(msgs, receiver8, nonDurable5);
+//         checkContainsAndAcknowledge(msgs, receiver9, nonDurable6);
+//         
+//         //n5
+//         checkEmpty(receiver10);
+//         checkContainsAndAcknowledge(msgs, receiver11, sharedDurable3);
+//         
+//         //n6
+//         checkEmpty(receiver12);
+//         checkContainsAndAcknowledge(msgs, receiver13, nonDurable7);
+//         
+//         //n7
+//         checkEmpty(receiver14);
+//         
+//         
+//         //Send 1 message at node2
+//         //========================
+//         
+//         msgs = sendMessages("topic", persistent, office2, 1, null);
+//         
+//         //n2
+//         checkContainsAndAcknowledge(msgs, receiver1, nonDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver2, nonDurable2);
+//         
+//         //n3
+//         checkContainsAndAcknowledge(msgs, receiver3, nonSharedDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver4, nonDurable3);
+//         
+//         //n4
+//         checkContainsAndAcknowledge(msgs, receiver5, sharedDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver6, nonSharedDurable2);
+//         checkContainsAndAcknowledge(msgs, receiver7, nonDurable4);
+//         checkContainsAndAcknowledge(msgs, receiver8, nonDurable5);
+//         checkContainsAndAcknowledge(msgs, receiver9, nonDurable6);
+//         
+//         //n5
+//         checkEmpty(receiver10);
+//         checkContainsAndAcknowledge(msgs, receiver11, sharedDurable3);
+//         
+//         //n6
+//         checkEmpty(receiver12);
+//         checkContainsAndAcknowledge(msgs, receiver13, nonDurable7);
+//         
+//         //n7
+//         checkEmpty(receiver14);
+//         
+//         //Send 1 message at node3
+//         //========================
+//         
+//         msgs = sendMessages("topic", persistent, office3, 1, null);
+//         
+//         //n2
+//         checkContainsAndAcknowledge(msgs, receiver1, nonDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver2, nonDurable2);
+//         
+//         //n3
+//         checkContainsAndAcknowledge(msgs, receiver3, nonSharedDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver4, nonDurable3);
+//         
+//         //n4
+//         checkContainsAndAcknowledge(msgs, receiver5, sharedDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver6, nonSharedDurable2);
+//         checkContainsAndAcknowledge(msgs, receiver7, nonDurable4);
+//         checkContainsAndAcknowledge(msgs, receiver8, nonDurable5);
+//         checkContainsAndAcknowledge(msgs, receiver9, nonDurable6);
+//         
+//         //n5
+//         checkEmpty(receiver10);
+//         checkContainsAndAcknowledge(msgs, receiver11, sharedDurable3);
+//         
+//         //n6
+//         checkEmpty(receiver12);
+//         checkContainsAndAcknowledge(msgs, receiver13, nonDurable7);
+//         
+//         //n7
+//         checkEmpty(receiver14);     
+//         
+//         //Send 1 message at node4
+//         //========================
+//         
+//         msgs = sendMessages("topic", persistent, office4, 1, null);         
+//               
+//         //n2
+//         checkContainsAndAcknowledge(msgs, receiver1, nonDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver2, nonDurable2);
+//         
+//         //n3
+//         checkContainsAndAcknowledge(msgs, receiver3, nonSharedDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver4, nonDurable3);
+//         
+//         //n4
+//         checkContainsAndAcknowledge(msgs, receiver5, sharedDurable1); // shared durable 1
+//         checkContainsAndAcknowledge(msgs, receiver6, nonSharedDurable2);
+//         checkContainsAndAcknowledge(msgs, receiver7, nonDurable4);
+//         checkContainsAndAcknowledge(msgs, receiver8, nonDurable5);
+//         checkContainsAndAcknowledge(msgs, receiver9, nonDurable6);
+//         
+//         //n5
+//         checkEmpty(receiver10);       //shared durable 1
+//         checkContainsAndAcknowledge(msgs, receiver11, sharedDurable3);     //shared durable 2    
+//         
+//         //n6
+//         checkEmpty(receiver12); // shared durable 2
+//         checkContainsAndAcknowledge(msgs, receiver13, nonDurable7); 
+//         
+//         //n7
+//         checkEmpty(receiver14);
+//         
+//         //Send 1 message at node5
+//         //========================
+//         
+//         msgs = sendMessages("topic", persistent, office5, 1, null);
+//             
+//         //n2
+//         checkContainsAndAcknowledge(msgs, receiver1, nonDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver2, nonDurable2);
+//         
+//         //n3
+//         checkContainsAndAcknowledge(msgs, receiver3, nonSharedDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver4, nonDurable3);
+//         
+//         //n4
+//         checkEmpty(receiver5);
+//         checkContainsAndAcknowledge(msgs, receiver6, nonSharedDurable2);
+//         checkContainsAndAcknowledge(msgs, receiver7, nonDurable4);
+//         checkContainsAndAcknowledge(msgs, receiver8, nonDurable5);
+//         checkContainsAndAcknowledge(msgs, receiver9, nonDurable6);
+//         
+//         //n5
+//         checkContainsAndAcknowledge(msgs, receiver10, sharedDurable2);
+//         checkContainsAndAcknowledge(msgs, receiver11, sharedDurable3);
+//         
+//         //n6
+//         checkEmpty(receiver12);
+//         checkContainsAndAcknowledge(msgs, receiver13, nonDurable7);
+//         
+//         //n7
+//         checkEmpty(receiver12);
+//         
+//         //Send 1 message at node6
+//         //========================
+//         
+//         msgs = sendMessages("topic", persistent, office6, 1, null);
+//             
+//         //n2
+//         checkContainsAndAcknowledge(msgs, receiver1, nonDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver2, nonDurable2);
+//         
+//         //n3
+//         checkContainsAndAcknowledge(msgs, receiver3, nonSharedDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver4, nonDurable3);
+//         
+//         //n4
+//         checkContainsAndAcknowledge(msgs, receiver5, sharedDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver6, nonSharedDurable2);
+//         checkContainsAndAcknowledge(msgs, receiver7, nonDurable4);
+//         checkContainsAndAcknowledge(msgs, receiver8, nonDurable5);
+//         checkContainsAndAcknowledge(msgs, receiver9, nonDurable6);
+//         
+//         //n5
+//         checkEmpty(receiver10);
+//        
+//         checkEmpty(receiver11);
+//         
+//         //n6
+//         checkContainsAndAcknowledge(msgs, receiver12, sharedDurable4);         
+//         checkContainsAndAcknowledge(msgs, receiver13, nonDurable7);
+//         
+//         //n7
+//         checkEmpty(receiver12);
+//         
+//         //Send 1 message at node7
+//         //========================
+//         
+//         msgs = sendMessages("topic", persistent, office7, 1, null);
+//
+//         //n2
+//         checkContainsAndAcknowledge(msgs, receiver1, nonDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver2, nonDurable2);
+//         
+//         //n3
+//         checkContainsAndAcknowledge(msgs, receiver3, nonSharedDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver4, nonDurable3);
+//         
+//         //n4
+//         checkContainsAndAcknowledge(msgs, receiver5, sharedDurable1);
+//         checkContainsAndAcknowledge(msgs, receiver6, nonSharedDurable2);
+//         checkContainsAndAcknowledge(msgs, receiver7, nonDurable4);
+//         checkContainsAndAcknowledge(msgs, receiver8, nonDurable5);
+//         checkContainsAndAcknowledge(msgs, receiver9, nonDurable6);
+//         
+//         //n5
+//         checkEmpty(receiver10);
+//         checkEmpty(receiver11);
+//         
+//         //n6
+//         checkEmpty(receiver12);
+//         checkContainsAndAcknowledge(msgs, receiver13, nonDurable7);
+//         
+//         //n7
+//         checkContainsAndAcknowledge(msgs, receiver14, sharedDurable5);
+//         
+//         if (checkNoMessageData())
+//         {
+//            fail("Message data still in database");
+//         }        
+//      }
+//      finally
+//      {
+//         if (office1 != null)
+//         {            
+//            office1.stop();
+//         }
+//         
+//         if (office2 != null)
+//         {
+//            office2.stop();
+//         }
+//         
+//         if (office3 != null)
+//         {            
+//            try
+//            {
+//               office3.unbindQueue("nonshareddurable1");
+//            }
+//            catch (Exception ignore)
+//            {   
+//               ignore.printStackTrace();
+//            }
+//            office3.stop();
+//         }
+//         
+//         if (office4 != null)
+//         {
+//            try
+//            {
+//               office4.unbindQueue("shareddurable1");
+//               office4.unbindQueue("nonshareddurable2");
+//            }
+//            catch (Exception ignore)
+//            {           
+//               ignore.printStackTrace();
+//            }
+//            office4.stop();
+//         }
+//         
+//         if (office5 != null)
+//         {      
+//            try
+//            {
+//               office5.unbindQueue("shareddurable1");
+//               office5.unbindQueue("shareddurable2");
+//            }
+//            catch (Exception ignore)
+//            {               
+//               ignore.printStackTrace();
+//            }
+//            office5.stop();
+//         }
+//         
+//         if (office6 != null)
+//         {         
+//            try
+//            {
+//               office6.unbindQueue("shareddurable2");
+//            }
+//            catch (Exception ignore)
+//            {               
+//               ignore.printStackTrace();
+//            }
+//            office6.stop();
+//         }
+//         
+//         if (office7 != null)
+//         {      
+//            try
+//            {
+//               office7.unbindQueue("shareddurable2");
+//            }
+//            catch (Exception ignore)
+//            {               
+//               ignore.printStackTrace();
+//            }
+//            office7.stop();
+//         }
+//        
+//      }
+//   }
+//   
+//   
+//
+//   
+//   
+//   protected void clusteredTransactionalRoute(boolean persistent) throws Throwable
+//   {
+//      PostOffice office1 = null;
+//      
+//      PostOffice office2 = null;
+//      
+//      try
+//      {   
+//         //Start two offices
+//         
+//         office1 = createPostOffice(1, "testgroup", sc, ms, pm, tr);
+//         office2 = createPostOffice(2, "testgroup", sc, ms, pm, tr);
+//     
+//         LocalClusteredQueue[] queues = new LocalClusteredQueue[16];
+//         Binding[] bindings = new Binding[16];
+//         
+//         queues[0] =
+//            new LocalClusteredQueue(1, "sub1", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         bindings[0] = office1.bindQueue(new SimpleCondition("topic1"), queues[0]);
+//         
+//         queues[1] =
+//            new LocalClusteredQueue(1, "sub2", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         bindings[1] = office1.bindQueue(new SimpleCondition("topic1"), queues[1]);
+//         
+//         queues[2] =
+//            new LocalClusteredQueue(2, "sub3", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         bindings[2] = office2.bindQueue(new SimpleCondition("topic1"), queues[2]);
+//         
+//         queues[3] =
+//            new LocalClusteredQueue(2, "sub4", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         bindings[3] = office2.bindQueue(new SimpleCondition("topic1"), queues[3]);
+//         
+//         queues[4] =
+//            new LocalClusteredQueue(2, "sub5", channelIDManager.getID(), ms, pm,
+//                                    true, true, -1, null);
+//         bindings[4] = office2.bindQueue(new SimpleCondition("topic1"), queues[4]);
+//         
+//         queues[5] =
+//            new LocalClusteredQueue(1, "sub6", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         bindings[5] = office1.bindQueue(new SimpleCondition("topic1"), queues[5]);
+//         
+//         queues[6] =
+//            new LocalClusteredQueue(1, "sub7", channelIDManager.getID(), ms, pm,
+//                                    true, true, -1, null);
+//         bindings[6] = office1.bindQueue(new SimpleCondition("topic1"), queues[6]);
+//         
+//         queues[7] =
+//            new LocalClusteredQueue(1, "sub8", channelIDManager.getID(), ms, pm,
+//                                    true, true, -1, null);
+//         bindings[7] = office1.bindQueue(new SimpleCondition("topic1"), queues[7]);
+//         
+//         queues[8] =
+//            new LocalClusteredQueue(1, "sub9", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         bindings[8] = office1.bindQueue(new SimpleCondition("topic2"), queues[8]);
+//         
+//         queues[9] =
+//            new LocalClusteredQueue(1, "sub10", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         bindings[9] = office1.bindQueue(new SimpleCondition("topic2"), queues[9]);
+//         
+//         queues[10] =
+//            new LocalClusteredQueue(2, "sub11", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         bindings[10] = office2.bindQueue(new SimpleCondition("topic2"), queues[10]);
+//         
+//         queues[11] =
+//            new LocalClusteredQueue(2, "sub12", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         bindings[11] = office2.bindQueue(new SimpleCondition("topic2"), queues[11]);
+//         
+//         queues[12] =
+//            new LocalClusteredQueue(2, "sub13", channelIDManager.getID(), ms, pm,
+//                                    true, true, -1, null);
+//         bindings[12] = office2.bindQueue(new SimpleCondition("topic2"), queues[12]);
+//         
+//         queues[13] =
+//            new LocalClusteredQueue(1, "sub14", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         bindings[13] = office1.bindQueue(new SimpleCondition("topic2"), queues[13]);
+//         
+//         queues[14] =
+//            new LocalClusteredQueue(1, "sub15", channelIDManager.getID(), ms, pm,
+//                                    true, true, -1, null);
+//         bindings[14] = office1.bindQueue(new SimpleCondition("topic2"), queues[14]);
+//         
+//         queues[15] =
+//            new LocalClusteredQueue(1, "sub16", channelIDManager.getID(), ms, pm,
+//                                    true, true, -1, null);
+//         bindings[15] = office1.bindQueue(new SimpleCondition("topic2"), queues[15]);
+//
+//         SimpleReceiver[] receivers = new SimpleReceiver[16];
+//         
+//         for (int i = 0; i < 16; i++)
+//         {
+//            receivers[i] = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//            queues[i].add(receivers[i]);
+//         }
+//         
+//         //First for topic 1
+//         
+//         Message msg1 = CoreMessageFactory.createCoreMessage(1, persistent, null);;      
+//         MessageReference ref1 = ms.reference(msg1);
+//         
+//         Message msg2 = CoreMessageFactory.createCoreMessage(2, persistent, null);;      
+//         MessageReference ref2 = ms.reference(msg2);
+//         
+//         Transaction tx = tr.createTransaction();
+//
+//         boolean routed = office1.route(ref1, new SimpleCondition("topic1"), tx);         
+//         assertTrue(routed);
+//         routed = office1.route(ref2, new SimpleCondition("topic1"), tx);         
+//         assertTrue(routed);
+//
+//         
+//         for (int i = 0; i < 16; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         tx.commit();
+//         
+//         //Messages are sent asych so may take some finite time to arrive
+//         Thread.sleep(1000);
+//         
+//         for (int i = 0; i < 8; i++)
+//         {         
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertEquals(2, msgs.size());
+//            Message msgRec1 = (Message)msgs.get(0);
+//            assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
+//            Message msgRec2 = (Message)msgs.get(1);
+//            assertEquals(msg2.getMessageID(), msgRec2.getMessageID());            
+//            receivers[i].acknowledge(msgRec1, null);
+//            receivers[i].acknowledge(msgRec2, null);
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);            
+//            assertTrue(msgs.isEmpty());                        
+//            receivers[i].clear();
+//         }
+//         
+//         for (int i = 8; i < 16; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         msg1 = CoreMessageFactory.createCoreMessage(1, persistent, null);;      
+//         ref1 = ms.reference(msg1);
+//         
+//         msg2 = CoreMessageFactory.createCoreMessage(2, persistent, null);;      
+//         ref2 = ms.reference(msg2);
+//         
+//         tx = tr.createTransaction();
+//
+//         routed = office1.route(ref1, new SimpleCondition("topic1"), tx);         
+//         assertTrue(routed);
+//         routed = office1.route(ref2, new SimpleCondition("topic1"), tx);         
+//         assertTrue(routed);
+//         
+//         //Messages are sent asych so may take some finite time to arrive
+//         Thread.sleep(1000);         
+//         
+//         for (int i = 0; i < 16; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         tx.rollback();
+//         
+//         for (int i = 0; i < 16; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         //Now send some non transactionally
+//         
+//         msg1 = CoreMessageFactory.createCoreMessage(1, persistent, null);
+//         ref1 = ms.reference(msg1);
+//         
+//         msg2 = CoreMessageFactory.createCoreMessage(2, persistent, null);
+//         ref2 = ms.reference(msg2);
+//         
+//         routed = office1.route(ref1, new SimpleCondition("topic1"), null);         
+//         assertTrue(routed);
+//         routed = office1.route(ref2, new SimpleCondition("topic1"), null);         
+//         assertTrue(routed);
+//         
+//         //Messages are sent asych so may take some finite time to arrive
+//         Thread.sleep(1000);         
+//         
+//         //And acknowledge transactionally
+//         
+//         tx = tr.createTransaction();
+//         
+//         for (int i = 0; i < 8; i++)
+//         {         
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertEquals(2, msgs.size());
+//            Message msgRec1 = (Message)msgs.get(0);
+//            assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
+//            Message msgRec2 = (Message)msgs.get(1);
+//            assertEquals(msg2.getMessageID(), msgRec2.getMessageID());      
+//                        
+//            receivers[i].acknowledge(msgRec1, tx);
+//            receivers[i].acknowledge(msgRec2, tx);
+//             
+//            int deliveringCount = queues[i].getDeliveringCount();
+//            
+//            assertEquals(2, deliveringCount);
+//                       
+//            receivers[i].clear();
+//         }
+//         
+//         for (int i = 8; i < 16; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         tx.commit();
+//         
+//         for (int i = 0; i < 16; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         
+//         // and the rollback
+//         
+//         msg1 = CoreMessageFactory.createCoreMessage(1, persistent, null);;      
+//         ref1 = ms.reference(msg1);
+//         
+//         msg2 = CoreMessageFactory.createCoreMessage(2, persistent, null);;      
+//         ref2 = ms.reference(msg2);
+//         
+//         routed = office1.route(ref1, new SimpleCondition("topic1"), null);         
+//         assertTrue(routed);
+//         routed = office1.route(ref2, new SimpleCondition("topic1"), null);         
+//         assertTrue(routed);
+//         
+//         Thread.sleep(1000);
+//                 
+//         tx = tr.createTransaction();
+//         
+//         for (int i = 0; i < 8; i++)
+//         {         
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertEquals(2, msgs.size());
+//            Message msgRec1 = (Message)msgs.get(0);
+//            assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
+//            Message msgRec2 = (Message)msgs.get(1);
+//            assertEquals(msg2.getMessageID(), msgRec2.getMessageID());      
+//                        
+//            receivers[i].acknowledge(msgRec1, tx);
+//            receivers[i].acknowledge(msgRec2, tx);
+//               
+//            int deliveringCount = queues[i].getDeliveringCount();
+//            
+//            assertEquals(2, deliveringCount);
+//            
+//         }
+//         
+//         for (int i = 8; i < 16; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         tx.rollback();
+//         
+//         for (int i = 0; i < 8; i++)
+//         {         
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertEquals(2, msgs.size());
+//            Message msgRec1 = (Message)msgs.get(0);
+//            assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
+//            Message msgRec2 = (Message)msgs.get(1);
+//            assertEquals(msg2.getMessageID(), msgRec2.getMessageID());      
+//                                 
+//            int deliveringCount = queues[i].getDeliveringCount();
+//            
+//            assertEquals(2, deliveringCount);
+//            
+//            receivers[i].acknowledge(msgRec1, null);
+//            receivers[i].acknowledge(msgRec2, null);
+//                           
+//            receivers[i].clear();
+//         }
+//         
+//         for (int i = 8; i < 16; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         
+//         // Now for topic 2
+//         
+//         msg1 = CoreMessageFactory.createCoreMessage(1, persistent, null);    
+//         ref1 = ms.reference(msg1);
+//         
+//         msg2 = CoreMessageFactory.createCoreMessage(2, persistent, null);     
+//         ref2 = ms.reference(msg2);
+//         
+//         tx = tr.createTransaction();
+//
+//         routed = office1.route(ref1, new SimpleCondition("topic2"), tx);         
+//         assertTrue(routed);
+//         routed = office1.route(ref2, new SimpleCondition("topic2"), tx);         
+//         assertTrue(routed);
+//         
+//         
+//         
+//         for (int i = 0; i < 16; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         tx.commit();
+//         
+//         //Messages are sent asych so may take some finite time to arrive
+//         Thread.sleep(1000);
+//         
+//         for (int i = 0; i < 8; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         for (int i = 8; i < 16; i++)
+//         {         
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertEquals(2, msgs.size());
+//            Message msgRec1 = (Message)msgs.get(0);
+//            assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
+//            Message msgRec2 = (Message)msgs.get(1);
+//            assertEquals(msg2.getMessageID(), msgRec2.getMessageID());            
+//            receivers[i].acknowledge(msgRec1, null);
+//            receivers[i].acknowledge(msgRec2, null);
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty()); 
+//            receivers[i].clear();
+//         }
+//         
+//         msg1 = CoreMessageFactory.createCoreMessage(1, persistent, null);;      
+//         ref1 = ms.reference(msg1);
+//         
+//         msg2 = CoreMessageFactory.createCoreMessage(2, persistent, null);;      
+//         ref2 = ms.reference(msg2);
+//         
+//         tx = tr.createTransaction();
+//
+//         routed = office1.route(ref1, new SimpleCondition("topic1"), tx);         
+//         assertTrue(routed);
+//         routed = office1.route(ref2, new SimpleCondition("topic1"), tx);         
+//         assertTrue(routed);
+//         
+//         for (int i = 0; i < 16; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         tx.rollback();
+//         
+//         for (int i = 0; i < 16; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         //Now send some non transactionally
+//         
+//         msg1 = CoreMessageFactory.createCoreMessage(1, persistent, null);      
+//         ref1 = ms.reference(msg1);
+//         
+//         msg2 = CoreMessageFactory.createCoreMessage(2, persistent, null);      
+//         ref2 = ms.reference(msg2);
+//         
+//         routed = office1.route(ref1, new SimpleCondition("topic2"), null);         
+//         assertTrue(routed);
+//         routed = office1.route(ref2, new SimpleCondition("topic2"), null);         
+//         assertTrue(routed);
+//         
+//         Thread.sleep(1000);
+//         
+//         //And acknowledge transactionally
+//         
+//         tx = tr.createTransaction();
+//         
+//         for (int i = 0; i < 8; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         for (int i = 8; i < 16; i++)
+//         {         
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertEquals(2, msgs.size());
+//            Message msgRec1 = (Message)msgs.get(0);
+//            assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
+//            Message msgRec2 = (Message)msgs.get(1);
+//            assertEquals(msg2.getMessageID(), msgRec2.getMessageID());      
+//                        
+//            receivers[i].acknowledge(msgRec1, tx);
+//            receivers[i].acknowledge(msgRec2, tx);
+//                        
+//            int deliveringCount = queues[i].getDeliveringCount();
+//            
+//            assertEquals(2, deliveringCount);
+//            
+//            receivers[i].clear();
+//         }
+//         
+//         
+//         
+//         tx.commit();
+//         
+//         for (int i = 0; i < 16; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         
+//         // and the rollback
+//         
+//         msg1 = CoreMessageFactory.createCoreMessage(1, persistent, null);;      
+//         ref1 = ms.reference(msg1);
+//         
+//         msg2 = CoreMessageFactory.createCoreMessage(2, persistent, null);;      
+//         ref2 = ms.reference(msg2);
+//         
+//         routed = office1.route(ref1, new SimpleCondition("topic2"), null);         
+//         assertTrue(routed);
+//         routed = office1.route(ref2, new SimpleCondition("topic2"), null);         
+//         assertTrue(routed);
+//         
+//         Thread.sleep(1000);
+//          
+//         tx = tr.createTransaction();
+//         
+//         for (int i = 0; i < 8; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         for (int i = 8; i < 16; i++)
+//         {         
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertEquals(2, msgs.size());
+//            Message msgRec1 = (Message)msgs.get(0);
+//            assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
+//            Message msgRec2 = (Message)msgs.get(1);
+//            assertEquals(msg2.getMessageID(), msgRec2.getMessageID());      
+//            
+//            
+//            receivers[i].acknowledge(msgRec1, tx);
+//            receivers[i].acknowledge(msgRec2, tx);
+//            
+//            
+//            int deliveringCount = queues[i].getDeliveringCount();
+//            
+//            assertEquals(2, deliveringCount);
+//         }
+//         
+//         
+//         
+//         tx.rollback();
+//         
+//         for (int i = 0; i < 8; i++)
+//         {
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//            msgs = queues[i].browse();
+//            assertNotNull(msgs);
+//            assertTrue(msgs.isEmpty());
+//         }
+//         
+//         for (int i = 8; i < 16; i++)
+//         {         
+//            List msgs = receivers[i].getMessages();
+//            assertNotNull(msgs);
+//            assertEquals(2, msgs.size());
+//            Message msgRec1 = (Message)msgs.get(0);
+//            assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
+//            Message msgRec2 = (Message)msgs.get(1);
+//            assertEquals(msg2.getMessageID(), msgRec2.getMessageID());      
+//                                              
+//            int deliveringCount = queues[i].getDeliveringCount();
+//            
+//            assertEquals(2, deliveringCount);
+//            
+//            receivers[i].acknowledge(msgRec1, null);
+//            receivers[i].acknowledge(msgRec2, null);             
+//            
+//            receivers[i].clear();
+//         }
+//         if (checkNoMessageData())
+//         {
+//            fail("Message data still in database");
+//         }
+//      }
+//      finally
+//      {
+//         if (office1 != null)
+//         {
+//            try
+//            {
+//               office1.unbindQueue("sub7");
+//               office1.unbindQueue("sub8");           
+//               office1.unbindQueue("sub15");
+//               office1.unbindQueue("sub16");
+//            }
+//            catch (Exception ignore)
+//            {
+//               ignore.printStackTrace();
+//            }
+//                        
+//            office1.stop();
+//         }
+//         
+//         if (office2 != null)
+//         {
+//            try
+//            {
+//               office2.unbindQueue("sub5");
+//               office2.unbindQueue("sub13");
+//            }
+//            catch (Exception ignore)
+//            {
+//               ignore.printStackTrace();
+//            }
+//            
+//            office2.stop();
+//         }
+//      }
+//   }
+   
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+   }
+
+   protected void tearDown() throws Exception
+   {
+      super.tearDown();
+   }
+
+   // Private --------------------------------------------------------------------------------------
+
+   // Inner classes --------------------------------------------------------------------------------
+
+}
+
+
+

Copied: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/DefaultClusteredPostOfficeWithDefaultRouterTest.java (from rev 2781, trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeWithDefaultRouterTest.java)
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/DefaultClusteredPostOfficeWithDefaultRouterTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/DefaultClusteredPostOfficeWithDefaultRouterTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,379 @@
+/*
+  * 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.postoffice;
+
+import java.util.List;
+
+import org.jboss.messaging.core.contract.PostOffice;
+import org.jboss.test.messaging.core.PostOfficeTestBase;
+import org.jboss.test.messaging.core.SimpleCondition;
+import org.jboss.test.messaging.core.SimpleReceiver;
+
+/**
+ * 
+ * A DefaultClusteredPostOfficeWithDefaultRouterTest
+ *
+ * @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$</tt>
+ *
+ * $Id$
+ *
+ */
+public class DefaultClusteredPostOfficeWithDefaultRouterTest extends PostOfficeTestBase
+{
+   // Constants ------------------------------------------------------------------------------------
+
+   // Static ---------------------------------------------------------------------------------------
+   
+   // Attributes -----------------------------------------------------------------------------------
+    
+   // Constructors ---------------------------------------------------------------------------------
+
+   public DefaultClusteredPostOfficeWithDefaultRouterTest(String name)
+   {
+      super(name);
+   }
+
+   // Public ---------------------------------------------------------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();
+   }
+
+   public void tearDown() throws Exception
+   {      
+      super.tearDown();
+   }
+   
+//   public void testNotLocalPersistent() throws Throwable
+//   {
+//      notLocal(true);
+//   }
+//   
+//   public void testNotLocalNonPersistent() throws Throwable
+//   {
+//      notLocal(false);
+//   }
+//   
+//   public void testLocalPersistent() throws Throwable
+//   {
+//      local(true);
+//   }
+//   
+//   public void testLocalNonPersistent() throws Throwable
+//   {
+//      local(false);
+//   }
+//   
+//   protected void notLocal(boolean persistent) throws Throwable
+//   {
+//      PostOffice office1 = null;
+//      
+//      PostOffice office2 = null;
+//      
+//      PostOffice office3 = null;
+//      
+//      PostOffice office4 = null;
+//      
+//      PostOffice office5 = null;
+//      
+//      PostOffice office6 = null;
+//          
+//      try
+//      {   
+//         office1 = createPostOffice(1, "testgroup", sc, ms, pm, tr);
+//         
+//         office2 = createPostOffice(2, "testgroup", sc, ms, pm, tr);
+//         
+//         office3 = createPostOffice(3, "testgroup", sc, ms, pm, tr);
+//         
+//         office4 = createPostOffice(4, "testgroup", sc, ms, pm, tr);
+//         
+//         office5 = createPostOffice(5, "testgroup", sc, ms, pm, tr);
+//         
+//         office6 = createPostOffice(6, "testgroup", sc, ms, pm, tr);
+//         
+//         LocalClusteredQueue queue1 =
+//            new LocalClusteredQueue(2, "queue1", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         office2.bindQueue(new SimpleCondition("topic"), queue1);
+//         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         queue1.add(receiver1);
+//         
+//         LocalClusteredQueue queue2 =
+//            new LocalClusteredQueue(3, "queue1", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         office3.bindQueue(new SimpleCondition("topic"), queue2);
+//         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         queue2.add(receiver2);
+//         
+//         LocalClusteredQueue queue3 =
+//            new LocalClusteredQueue(4, "queue1", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         office4.bindQueue(new SimpleCondition("topic"), queue3);
+//         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         queue3.add(receiver3);
+//         
+//         LocalClusteredQueue queue4 =
+//            new LocalClusteredQueue(5, "queue1", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         office5.bindQueue(new SimpleCondition("topic"), queue4);
+//         SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         queue4.add(receiver4);
+//         
+//         LocalClusteredQueue queue5 =
+//            new LocalClusteredQueue(6, "queue1", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         office6.bindQueue(new SimpleCondition("topic"), queue5);
+//         SimpleReceiver receiver5 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         queue5.add(receiver5);
+//               
+//         List msgs = sendMessages("topic", persistent, office1, 1, null);         
+//         checkContainsAndAcknowledge(msgs, receiver1, queue1);         
+//         checkEmpty(receiver2);
+//         checkEmpty(receiver3);
+//         checkEmpty(receiver4);
+//         checkEmpty(receiver5);
+//         
+//         msgs = sendMessages("topic", persistent, office1, 1, null);         
+//         checkEmpty(receiver1);
+//         checkContainsAndAcknowledge(msgs, receiver2, queue1);                  
+//         checkEmpty(receiver3);
+//         checkEmpty(receiver4);
+//         checkEmpty(receiver5);
+//         
+//         msgs = sendMessages("topic", persistent, office1, 1, null);         
+//         checkEmpty(receiver1);
+//         checkEmpty(receiver2);
+//         checkContainsAndAcknowledge(msgs, receiver3, queue1);                           
+//         checkEmpty(receiver4);
+//         checkEmpty(receiver5);
+//         
+//         msgs = sendMessages("topic", persistent, office1, 1, null);         
+//         checkEmpty(receiver1);
+//         checkEmpty(receiver2);
+//         checkEmpty(receiver3);
+//         checkContainsAndAcknowledge(msgs, receiver4, queue1);                                    
+//         checkEmpty(receiver5);
+//         
+//         msgs = sendMessages("topic", persistent, office1, 1, null);         
+//         checkEmpty(receiver1);
+//         checkEmpty(receiver2);
+//         checkEmpty(receiver3);
+//         checkEmpty(receiver4);
+//         checkContainsAndAcknowledge(msgs, receiver5, queue1); 
+//         
+//         msgs = sendMessages("topic", persistent, office1, 1, null);         
+//         checkContainsAndAcknowledge(msgs, receiver1, queue1);         
+//         checkEmpty(receiver2);
+//         checkEmpty(receiver3);
+//         checkEmpty(receiver4);
+//         checkEmpty(receiver5);
+//         
+//         msgs = sendMessages("topic", persistent, office1, 1, null);         
+//         checkEmpty(receiver1);
+//         checkContainsAndAcknowledge(msgs, receiver2, queue1);                  
+//         checkEmpty(receiver3);
+//         checkEmpty(receiver4);
+//         checkEmpty(receiver5);
+//         
+//                     
+//      }
+//      finally
+//      {
+//         if (office1 != null)
+//         {            
+//            office1.stop();
+//         }
+//         
+//         if (office2 != null)
+//         {
+//            office2.stop();
+//         }
+//         
+//         if (office3 != null)
+//         {            
+//            office3.stop();
+//         }
+//         
+//         if (office4 != null)
+//         {
+//            office4.stop();
+//         }
+//         
+//         if (office5 != null)
+//         {            
+//            office5.stop();
+//         }
+//         
+//         if (office6 != null)
+//         {
+//            office6.stop();
+//         }
+//      }
+//   }
+//   
+//   
+//   
+//   
+//   protected void local(boolean persistent) throws Throwable
+//   {
+//      PostOffice office1 = null;
+//      PostOffice office2 = null;
+//      PostOffice office3 = null;
+//      PostOffice office4 = null;
+//      PostOffice office5 = null;
+//      PostOffice office6 = null;
+//          
+//      try
+//      {   
+//         office1 = createPostOffice(1, "testgroup", sc, ms, pm, tr);
+//         office2 = createPostOffice(2, "testgroup", sc, ms, pm, tr);
+//         office3 = createPostOffice(3, "testgroup", sc, ms, pm, tr);
+//         office4 = createPostOffice(4, "testgroup", sc, ms, pm, tr);
+//         office5 = createPostOffice(5, "testgroup", sc, ms, pm, tr);
+//         office6 = createPostOffice(6, "testgroup", sc, ms, pm, tr);
+//         
+//         LocalClusteredQueue queue1 =
+//            new LocalClusteredQueue(2, "queue1", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         office2.bindQueue(new SimpleCondition("topic"), queue1);
+//         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         queue1.add(receiver1);
+//         
+//         LocalClusteredQueue queue2 =
+//            new LocalClusteredQueue(3, "queue1", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         office3.bindQueue(new SimpleCondition("topic"), queue2);
+//         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         queue2.add(receiver2);
+//         
+//         LocalClusteredQueue queue3 =
+//            new LocalClusteredQueue(4, "queue1", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         office4.bindQueue(new SimpleCondition("topic"), queue3);
+//         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         queue3.add(receiver3);
+//         
+//         LocalClusteredQueue queue4 =
+//            new LocalClusteredQueue(5, "queue1", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         office5.bindQueue(new SimpleCondition("topic"), queue4);
+//         SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         queue4.add(receiver4);
+//         
+//         LocalClusteredQueue queue5 =
+//            new LocalClusteredQueue(6, "queue1", channelIDManager.getID(), ms, pm,
+//                                    true, false, -1, null);
+//         office6.bindQueue(new SimpleCondition("topic"), queue5);
+//         SimpleReceiver receiver5 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+//         queue5.add(receiver5);
+//               
+//         List msgs = sendMessages("topic", persistent, office2, 3, null);         
+//         checkContainsAndAcknowledge(msgs, receiver1, queue1);         
+//         checkEmpty(receiver2);
+//         checkEmpty(receiver3);
+//         checkEmpty(receiver4);
+//         checkEmpty(receiver5);
+//         
+//         msgs = sendMessages("topic", persistent, office2, 3, null);         
+//         checkContainsAndAcknowledge(msgs, receiver1, queue1);         
+//         checkEmpty(receiver2);
+//         checkEmpty(receiver3);
+//         checkEmpty(receiver4);
+//         checkEmpty(receiver5);
+//         
+//         msgs = sendMessages("topic", persistent, office2, 3, null);         
+//         checkContainsAndAcknowledge(msgs, receiver1, queue1);         
+//         checkEmpty(receiver2);
+//         checkEmpty(receiver3);
+//         checkEmpty(receiver4);
+//         checkEmpty(receiver5);
+//         
+//         
+//         msgs = sendMessages("topic", persistent, office3, 3, null); 
+//         checkEmpty(receiver1);
+//         checkContainsAndAcknowledge(msgs, receiver2, queue1);                  
+//         checkEmpty(receiver3);
+//         checkEmpty(receiver4);
+//         checkEmpty(receiver5);
+//         
+//         msgs = sendMessages("topic", persistent, office3, 3, null); 
+//         checkEmpty(receiver1);
+//         checkContainsAndAcknowledge(msgs, receiver2, queue1);                  
+//         checkEmpty(receiver3);
+//         checkEmpty(receiver4);
+//         checkEmpty(receiver5);
+//         
+//         msgs = sendMessages("topic", persistent, office3, 3, null); 
+//         checkEmpty(receiver1);
+//         checkContainsAndAcknowledge(msgs, receiver2, queue1);                  
+//         checkEmpty(receiver3);
+//         checkEmpty(receiver4);
+//         checkEmpty(receiver5);
+//         
+//                     
+//      }
+//      finally
+//      {
+//         if (office1 != null)
+//         {            
+//            office1.stop();
+//         }
+//         
+//         if (office2 != null)
+//         {
+//            office2.stop();
+//         }
+//         
+//         if (office3 != null)
+//         {            
+//            office3.stop();
+//         }
+//         
+//         if (office4 != null)
+//         {
+//            office4.stop();
+//         }
+//         
+//         if (office5 != null)
+//         {            
+//            office5.stop();
+//         }
+//         
+//         if (office6 != null)
+//         {
+//            office6.stop();
+//         }
+//      }
+//   }
+   
+   // Private --------------------------------------------------------------------------------------
+
+   // Inner classes --------------------------------------------------------------------------------
+
+}
+
+
+

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/DefaultPostOfficeTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/DefaultPostOfficeTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/DefaultPostOfficeTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,1097 +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.postoffice;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.contract.PostOffice;
-import org.jboss.messaging.core.plugin.postoffice.Binding;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.test.messaging.core.SimpleCondition;
-import org.jboss.test.messaging.core.SimpleFilter;
-import org.jboss.test.messaging.core.SimpleReceiver;
-import org.jboss.test.messaging.core.plugin.base.PostOfficeTestBase;
-import org.jboss.test.messaging.util.CoreMessageFactory;
-
-/**
- * 
- * A DefaultPostOfficeTest
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public class DefaultPostOfficeTest extends PostOfficeTestBase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-   // Constructors --------------------------------------------------
-
-   public DefaultPostOfficeTest(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-
-   public final void testBind() throws Throwable
-   {
-      PostOffice office1 = null;
-      
-      PostOffice office2 = null;
-      
-      PostOffice office3 = null;
-      
-      try
-      {             
-         office1 = createPostOffice();
-         
-         //Bind one durable
-         
-         PagingFilteredQueue queue1 =
-            new PagingFilteredQueue("durableQueue", channelIDManager.getID(), ms, pm, true, true,
-                                    -1, null);
-         
-         
-         Binding binding1 =
-            office1.bindQueue(new SimpleCondition("condition1"), queue1);
-         
-         //Binding twice with the same name should fail      
-         try
-         {
-            office1.bindQueue(new SimpleCondition("condition1"), queue1);
-            fail();
-         }
-         catch (IllegalArgumentException e)
-         {
-            //Ok
-         }
-               
-         //Bind one non durable
-         PagingFilteredQueue queue2 =
-            new PagingFilteredQueue("nonDurableQueue", channelIDManager.getID(), ms, pm, true,
-                                    false, -1, null);
-         
-         Binding binding2 =
-            office1.bindQueue(new SimpleCondition("condition2"), queue2);
-         
-         //Check they're there
-         
-         Binding binding3 = office1.getBindingForQueueName("durableQueue");
-         assertNotNull(binding3);
-         assertTrue(binding1 == binding3);
-         assertEquivalent(binding1, binding3);
-         assertTrue(binding3.getQueue().isActive());
-         assertEquals(true, binding3.getQueue().isRecoverable());
-         
-         
-         Binding binding4 = office1.getBindingForQueueName("nonDurableQueue");
-         assertNotNull(binding4);
-         assertTrue(binding2 == binding4);
-         assertEquivalent(binding2, binding4);
-         assertTrue(binding4.getQueue().isActive());
-         assertEquals(false, binding4.getQueue().isRecoverable());
-         
-         office1.stop();
-         
-         //Throw away the office and create another
-         office2 = createPostOffice();
-         
-         //Only one binding should be there
-         Binding binding5 = office2.getBindingForQueueName("durableQueue");
-         assertNotNull(binding5);
-         assertEquivalent(binding1, binding5);
-         //Should be inactive
-         assertFalse(binding5.getQueue().isActive());
-         
-         Binding binding6 = office2.getBindingForQueueName("nonDurableQueue");
-         assertNull(binding6);
-         
-         //Unbind the binding
-         Binding binding7 = office2.unbindQueue("durableQueue");
-         assertNotNull(binding7);
-         assertEquivalent(binding1, binding7);
-         
-         //Make sure no longer there
-         Binding binding8 = office2.getBindingForQueueName("durableQueue");
-         assertNull(binding8);
-         
-         office2.stop();
-         
-         //Throw away office and start another
-         office3 = createPostOffice();
-         
-         //Make sure not there
-         Binding binding9 = office3.getBindingForQueueName("durableQueue");
-         assertNull(binding9);
-         
-         
-      }
-      finally
-      {
-         if (office1 != null)
-         {
-            office1.stop();
-         }
-         
-         if (office2 != null)
-         {
-            office2.stop();
-         }
-         
-         if (office3 != null)
-         {
-            office2.stop();
-         }
-         
-         if (checkNoBindingData())
-         {
-            fail("Binding data still in database");
-         }
-      }
-            
-   }
-   
-   public final void testListBindings() throws Throwable
-   {
-      PostOffice office = null;
-      
-      try
-      {      
-         office = createPostOffice();
-         
-         PagingFilteredQueue queue1 = new PagingFilteredQueue("queue1", channelIDManager.getID(), ms, pm, true, false, -1, null);
-         
-         Binding binding1 =
-            office.bindQueue(new SimpleCondition("condition1"), queue1);
-         
-         PagingFilteredQueue queue2 = new PagingFilteredQueue("queue2", channelIDManager.getID(), ms, pm, true, false, -1, null);
-         
-         Binding binding2 =
-            office.bindQueue(new SimpleCondition("condition1"), queue2);
-         
-         PagingFilteredQueue queue3 = new PagingFilteredQueue("queue3", channelIDManager.getID(), ms, pm, true, false, -1, null);
-         
-         Binding binding3 =
-            office.bindQueue(new SimpleCondition("condition1"), queue3);
-         
-         PagingFilteredQueue queue4 = new PagingFilteredQueue("queue4", channelIDManager.getID(), ms, pm, true, false, -1, null);
-         
-         Binding binding4 =
-            office.bindQueue(new SimpleCondition("condition1"), queue4);
-         
-         PagingFilteredQueue queue5 = new PagingFilteredQueue("queue5", channelIDManager.getID(), ms, pm, true, false, -1, null);
-         
-         Binding binding5 =
-            office.bindQueue(new SimpleCondition("condition2"), queue5);
-         
-         PagingFilteredQueue queue6 = new PagingFilteredQueue("queue6", channelIDManager.getID(), ms, pm, true, false, -1, null);
-         
-         Binding binding6 =
-            office.bindQueue(new SimpleCondition("condition2"), queue6);
-         
-         PagingFilteredQueue queue7 = new PagingFilteredQueue("queue7", channelIDManager.getID(), ms, pm, true, false, -1, null);
-         
-         Binding binding7 =
-            office.bindQueue(new SimpleCondition("condition2"), queue7);
-         
-         PagingFilteredQueue queue8 = new PagingFilteredQueue("queue8", channelIDManager.getID(), ms, pm, true, false, -1, null);
-         
-         Binding binding8 =
-            office.bindQueue(new SimpleCondition("condition2"), queue8);
-         
-         
-         Collection bindings = office.getBindingsForCondition(new SimpleCondition("dummy"));
-         assertNotNull(bindings);
-         assertTrue(bindings.isEmpty());
-         
-         //We don't match on substrings
-         bindings = office.getBindingsForCondition(new SimpleCondition("condition123"));
-         assertNotNull(bindings);
-         assertTrue(bindings.isEmpty());
-         
-         //We don't currently support hierarchies
-         bindings = office.getBindingsForCondition(new SimpleCondition("condition1.subcondition"));
-         assertNotNull(bindings);
-         assertTrue(bindings.isEmpty());
-         
-         //We currently just do an exact match
-         bindings = office.getBindingsForCondition(new SimpleCondition("condition1"));
-         assertNotNull(bindings);
-         assertEquals(4, bindings.size());
-         
-         Iterator iter = bindings.iterator();
-         assertEquivalent((Binding)iter.next(), binding1);
-         assertEquivalent((Binding)iter.next(), binding2);
-         assertEquivalent((Binding)iter.next(), binding3);
-         assertEquivalent((Binding)iter.next(), binding4);
-         
-         bindings = office.getBindingsForCondition(new SimpleCondition("condition2"));
-         assertNotNull(bindings);
-         assertEquals(4, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent((Binding)iter.next(), binding5);
-         assertEquivalent((Binding)iter.next(), binding6);
-         assertEquivalent((Binding)iter.next(), binding7);
-         assertEquivalent((Binding)iter.next(), binding8);
-      }
-      finally
-      {
-         if (office != null)
-         {
-            office.stop();
-         }
-      }
-         
-   }
-   
-   public void testRouteNonPersistentWithFilter() throws Throwable
-   {
-      routeWithFilter(false);
-   }
-   
-   public void testRoutePersistentWithFilter() throws Throwable
-   {
-      routeWithFilter(true);
-   }
-   
-   public final void testRoutePersistent() throws Throwable
-   {
-      route(true);
-   }
-   
-   public final void testRouteNonPersistent() throws Throwable
-   {
-      route(false);
-   }
-   
-   public final void testRouteTransactionalPersistent() throws Throwable
-   {
-      routeTransactional(true);
-   }
-   
-   public final void testRouteTransactionalNonPersistent() throws Throwable
-   {
-      routeTransactional(false);
-   }
-   
-      
-   public final void testRouteInactive() throws Throwable
-   {
-      PostOffice postOffice = null;
-      
-      try
-      {
-      
-         postOffice = createPostOffice();
-         
-         PagingFilteredQueue queue1 =
-            new PagingFilteredQueue("queue1", channelIDManager.getID(), ms, pm, true, false,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("topic1"), queue1);
-         
-         PagingFilteredQueue queue2 =
-            new PagingFilteredQueue("queue2", channelIDManager.getID(), ms, pm, true, false,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("topic1"), queue2);
-         
-         PagingFilteredQueue queue3 =
-            new PagingFilteredQueue("queue3", channelIDManager.getID(), ms, pm, true, false,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("topic1"), queue3);
-         
-         PagingFilteredQueue queue4 =
-            new PagingFilteredQueue("queue4", channelIDManager.getID(), ms, pm, true, false,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("topic2"), queue4);
-         
-         PagingFilteredQueue queue5 =
-            new PagingFilteredQueue("queue5", channelIDManager.getID(), ms, pm, true, false,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("topic2"), queue5);
-         
-         PagingFilteredQueue queue6 =
-            new PagingFilteredQueue("queue6", channelIDManager.getID(), ms, pm, true, false,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("topic2"), queue6);
-      
-         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue1.add(receiver1);
-         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue2.add(receiver2);
-         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue3.add(receiver3);
-         SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue4.add(receiver4);
-         SimpleReceiver receiver5 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue5.add(receiver5);
-         SimpleReceiver receiver6 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue6.add(receiver6);
-         
-         queue1.deactivate();
-         queue2.deactivate();
-         queue5.deactivate();
-         queue6.deactivate();
-         
-         assertFalse(queue1.isActive());      
-         assertFalse(queue2.isActive());
-         assertFalse(queue5.isActive());
-         assertFalse(queue6.isActive()); 
-         assertTrue(queue3.isActive());
-         assertTrue(queue4.isActive());      
-         
-         Message msg1 = CoreMessageFactory.createCoreMessage(1);      
-         MessageReference ref1 = ms.reference(msg1);
-         
-         boolean routed = postOffice.route(ref1, new SimpleCondition("topic1"), null);      
-         assertTrue(routed);
-         
-         List msgs = receiver1.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = receiver2.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = receiver3.getMessages();
-         assertNotNull(msgs);
-         assertEquals(1, msgs.size());
-         Message msgRec = (Message)msgs.get(0);
-         assertTrue(msg1 == msgRec);
-         receiver3.acknowledge(msgRec, null);
-         msgs = queue3.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());  
-         
-         msgs = receiver4.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = receiver5.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = receiver6.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         receiver3.clear();
-                     
-         Message msg2 = CoreMessageFactory.createCoreMessage(2);      
-         MessageReference ref2 = ms.reference(msg2);
-         
-         routed = postOffice.route(ref2, new SimpleCondition("topic2"), null);      
-         assertTrue(routed);
-         
-         msgs = receiver1.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = receiver2.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = receiver3.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());      
-         
-         msgs = receiver4.getMessages();
-         assertNotNull(msgs);
-         assertEquals(1, msgs.size());
-         msgRec = (Message)msgs.get(0);
-         assertTrue(msg2 == msgRec);
-         receiver4.acknowledge(msgRec, null);
-         msgs = queue4.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());  
-         
-         msgs = receiver5.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = receiver6.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         if (checkNoMessageData())
-         {
-            fail("data still in database");
-         }
-      }
-      finally
-      {
-         if (postOffice != null)
-         {
-            postOffice.stop();
-         }
-         
-      }
-   
-   }
-
-   public final void testRouteNoBinding() throws Throwable
-   {
-      PostOffice postOffice = null;
-      
-      try
-      {      
-         postOffice = createPostOffice();
-         
-         PagingFilteredQueue queue1 =
-            new PagingFilteredQueue("queue1", channelIDManager.getID(), ms, pm, true, false,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("condition1"), queue1);
-              
-         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
-         queue1.add(receiver1);
-   
-         assertTrue(queue1.isActive());
-   
-         Message msg1 = CoreMessageFactory.createCoreMessage(1);      
-         MessageReference ref1 = ms.reference(msg1);
-         
-         boolean routed =
-            postOffice.route(ref1, new SimpleCondition("this won't match anything"), null);
-         
-         assertFalse(routed);
-               
-         List msgs = receiver1.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());  
-         
-         if (checkNoMessageData())
-         {
-            fail("data still in database");
-         }
-         
-      }
-      finally
-      {
-         if (postOffice != null)
-         {
-            postOffice.stop();
-         }
-         
-      }
-   }
-   
-   
-   
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-   
-   protected void routeWithFilter(boolean persistentMessage) throws Throwable
-   {
-      PostOffice postOffice = null;
-      
-      try
-      {      
-         postOffice = createPostOffice();
-         
-         SimpleFilter filter = new SimpleFilter(2);
-      
-         PagingFilteredQueue queue1 =
-            new PagingFilteredQueue("queue1", channelIDManager.getID(), ms, pm, true, false,
-                                    -1, filter);
-         
-         postOffice.bindQueue(new SimpleCondition("topic1"), queue1);
-         
-         PagingFilteredQueue queue2 =
-            new PagingFilteredQueue("queue2", channelIDManager.getID(), ms, pm, true, false,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("topic1"), queue2);
-         
-         PagingFilteredQueue queue3 =
-            new PagingFilteredQueue("queue3", channelIDManager.getID(), ms, pm, true, false,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("topic1"), queue3);
-         
-         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue1.add(receiver1);
-         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue2.add(receiver2);
-         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue3.add(receiver3);
-         
-         Message msg1 = CoreMessageFactory.createCoreMessage(1);      
-         MessageReference ref1 = ms.reference(msg1);         
-         boolean routed = postOffice.route(ref1, new SimpleCondition("topic1"), null);      
-         assertTrue(routed);
-         Message msg2 = CoreMessageFactory.createCoreMessage(2);      
-         MessageReference ref2 = ms.reference(msg2);         
-         routed = postOffice.route(ref2, new SimpleCondition("topic1"), null);      
-         assertTrue(routed);
-         Message msg3 = CoreMessageFactory.createCoreMessage(3);      
-         MessageReference ref3 = ms.reference(msg3);         
-         routed = postOffice.route(ref3, new SimpleCondition("topic1"), null);      
-         assertTrue(routed);
-         
-         List msgs = receiver1.getMessages();
-         assertNotNull(msgs);
-         assertEquals(1, msgs.size());
-         Message msgRec = (Message)msgs.get(0);
-         assertTrue(msg2 == msgRec);
-         receiver1.acknowledge(msgRec, null);
-         msgs = queue1.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());  
-         
-         msgs = receiver2.getMessages();
-         assertNotNull(msgs);
-         assertEquals(3, msgs.size());
-         Message msgRec1 = (Message)msgs.get(0);
-         assertTrue(msg1 == msgRec1);
-         Message msgRec2 = (Message)msgs.get(1);
-         assertTrue(msg2 == msgRec2);
-         Message msgRec3 = (Message)msgs.get(2);
-         assertTrue(msg3 == msgRec3);
-          
-         receiver2.acknowledge(msgRec1, null);
-         receiver2.acknowledge(msgRec2, null);
-         receiver2.acknowledge(msgRec3, null);
-         msgs = queue2.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());  
-         
-         msgs = receiver3.getMessages();
-         assertNotNull(msgs);
-         assertEquals(3, msgs.size());
-         msgRec1 = (Message)msgs.get(0);
-         assertTrue(msg1 == msgRec1);
-         msgRec2 = (Message)msgs.get(1);
-         assertTrue(msg2 == msgRec2);
-         msgRec3 = (Message)msgs.get(2);
-         assertTrue(msg3 == msgRec3);
-          
-         receiver3.acknowledge(msgRec1, null);
-         receiver3.acknowledge(msgRec2, null);
-         receiver3.acknowledge(msgRec3, null);
-         msgs = queue3.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty()); 
-         
-         if (checkNoMessageData())
-         {
-            fail("data still in database");
-         }
-         
-      }
-      finally
-      {
-         if (postOffice != null)
-         {
-            postOffice.stop();
-         }
-        
-      }
-   }
-   
-   protected void route(boolean persistentMessage) throws Throwable
-   {
-      PostOffice postOffice = null;
-      
-      try
-      {      
-         postOffice = createPostOffice();
-      
-         PagingFilteredQueue queue1 =
-            new PagingFilteredQueue("queue1", channelIDManager.getID(), ms, pm, true, false,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("topic1"), queue1);
-         
-         PagingFilteredQueue queue2 =
-            new PagingFilteredQueue("queue2", channelIDManager.getID(), ms, pm, true, false,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("topic1"), queue2);
-         
-         PagingFilteredQueue queue3 =
-            new PagingFilteredQueue("queue3", channelIDManager.getID(), ms, pm, true, false,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("topic1"), queue3);
-         
-         PagingFilteredQueue queue4 =
-            new PagingFilteredQueue("queue4", channelIDManager.getID(), ms, pm, true, true,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("topic2"), queue4);
-         
-         PagingFilteredQueue queue5 =
-            new PagingFilteredQueue("queue5", channelIDManager.getID(), ms, pm, true, true,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("topic2"), queue5);
-         
-         PagingFilteredQueue queue6 =
-            new PagingFilteredQueue("queue6", channelIDManager.getID(), ms, pm, true, true,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("topic2"), queue6);
-      
-         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
-         queue1.add(receiver1);
-         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
-         queue2.add(receiver2);
-         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
-         queue3.add(receiver3);
-         SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
-         queue4.add(receiver4);
-         SimpleReceiver receiver5 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
-         queue5.add(receiver5);
-         SimpleReceiver receiver6 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
-         queue6.add(receiver6);
-         
-         assertTrue(queue1.isActive());      
-         assertTrue(queue2.isActive());
-         assertTrue(queue3.isActive());      
-         assertTrue(queue4.isActive());
-         assertTrue(queue5.isActive());      
-         assertTrue(queue6.isActive());
-         
-         Message msg1 = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
-         MessageReference ref1 = ms.reference(msg1);
-         
-         boolean routed = postOffice.route(ref1, new SimpleCondition("topic1"), null);      
-         assertTrue(routed);
-         
-         List msgs = receiver1.getMessages();
-         assertNotNull(msgs);
-         assertEquals(1, msgs.size());
-         Message msgRec = (Message)msgs.get(0);
-         assertTrue(msg1 == msgRec);
-         receiver1.acknowledge(msgRec, null);
-         msgs = queue1.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = receiver2.getMessages();
-         assertNotNull(msgs);
-         assertEquals(1, msgs.size());
-         msgRec = (Message)msgs.get(0);
-         assertTrue(msg1 == msgRec);
-         receiver2.acknowledge(msgRec, null);
-         msgs = queue2.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = receiver3.getMessages();
-         assertNotNull(msgs);
-         assertEquals(1, msgs.size());
-         msgRec = (Message)msgs.get(0);
-         assertTrue(msg1 == msgRec);
-         receiver3.acknowledge(msgRec, null);
-         msgs = queue3.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = receiver4.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = receiver5.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = receiver6.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         receiver1.clear();
-         receiver2.clear();
-         receiver3.clear();
-         
-         
-         Message msg2 = CoreMessageFactory.createCoreMessage(2, persistentMessage, null);      
-         MessageReference ref2 = ms.reference(msg2);
-         
-         routed = postOffice.route(ref2, new SimpleCondition("topic2"), null);      
-         assertTrue(routed);
-         
-         msgs = receiver4.getMessages();
-         assertNotNull(msgs);
-         assertEquals(1, msgs.size());
-         msgRec = (Message)msgs.get(0);
-         assertTrue(msg2 == msgRec);
-         receiver4.acknowledge(msgRec, null);
-         msgs = queue4.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = receiver5.getMessages();
-         assertNotNull(msgs);
-         assertEquals(1, msgs.size());
-         msgRec = (Message)msgs.get(0);
-         assertTrue(msg2 == msgRec);
-         receiver5.acknowledge(msgRec, null);
-         msgs = queue5.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = receiver6.getMessages();
-         assertNotNull(msgs);
-         assertEquals(1, msgs.size());
-         msgRec = (Message)msgs.get(0);
-         assertTrue(msg2 == msgRec);
-         receiver6.acknowledge(msgRec, null);
-         msgs = queue6.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());    
-         
-         msgs = receiver1.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = receiver2.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = receiver3.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-      }
-      finally
-      {
-         if (postOffice != null)
-         {
-            postOffice.stop();
-         }
-         
-         if (checkNoMessageData())
-         {
-            fail("data still in database");
-         }
-      }
-   }
-   
-   protected void routeTransactional(boolean persistentMessage) throws Throwable
-   {
-      PostOffice postOffice = null;
-      
-      try
-      {      
-         postOffice = createPostOffice();
-      
-         PagingFilteredQueue queue1 =
-            new PagingFilteredQueue("queue1", channelIDManager.getID(), ms, pm, true, false,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("topic1"), queue1);
-         
-         PagingFilteredQueue queue2 =
-            new PagingFilteredQueue("queue2", channelIDManager.getID(), ms, pm, true, true,
-                                    -1, null);
-         
-         postOffice.bindQueue(new SimpleCondition("topic1"), queue2);
-          
-         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
-         queue1.add(receiver1);
-
-         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
-         queue2.add(receiver2);
-   
-         assertTrue(queue1.isActive());
-         assertTrue(queue2.isActive());
-   
-         Message msg1 = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
-         MessageReference ref1 = ms.reference(msg1);
-         
-         Message msg2 = CoreMessageFactory.createCoreMessage(2, persistentMessage, null);      
-         MessageReference ref2 = ms.reference(msg2);
-         
-         Transaction tx = tr.createTransaction();
-         
-         boolean routed = postOffice.route(ref1, new SimpleCondition("topic1"), tx);            
-         assertTrue(routed);
-         routed = postOffice.route(ref2, new SimpleCondition("topic1"), tx);            
-         assertTrue(routed);
-               
-         List msgs = queue1.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         msgs = queue2.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         tx.commit();
-         
-         msgs = receiver1.getMessages();
-         assertNotNull(msgs);
-         assertEquals(2, msgs.size());
-         Message msgRec1 = (Message)msgs.get(0);
-         Message msgRec2 = (Message)msgs.get(1);
-         assertTrue(msgRec1 == msg1);
-         assertTrue(msgRec2 == msg2);
-         
-         msgs = receiver2.getMessages();
-         assertNotNull(msgs);
-         assertEquals(2, msgs.size());
-         msgRec1 = (Message)msgs.get(0);
-         msgRec2 = (Message)msgs.get(1);
-         assertTrue(msgRec1 == msg1);
-         assertTrue(msgRec2 == msg2);
-         
-         //Acknowledge non transactionally
-         receiver1.acknowledge(msgRec1, null);
-         receiver1.acknowledge(msgRec2, null);
-         
-         receiver2.acknowledge(msgRec1, null);
-         receiver2.acknowledge(msgRec2, null);
-   
-         msgs = queue1.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty()); 
-         
-         receiver1.clear();
-         
-         msgs = queue2.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty()); 
-         
-         receiver2.clear();
-              
-         Message msg3 = CoreMessageFactory.createCoreMessage(3, persistentMessage, null);      
-         MessageReference ref3 = ms.reference(msg3);
-         
-         Message msg4 = CoreMessageFactory.createCoreMessage(4, persistentMessage, null);      
-         MessageReference ref4 = ms.reference(msg4);
-         
-         tx = tr.createTransaction();
-         
-         routed = postOffice.route(ref3, new SimpleCondition("topic1"), tx);            
-         assertTrue(routed);
-         routed = postOffice.route(ref4, new SimpleCondition("topic1"), tx);            
-         assertTrue(routed);
-               
-         msgs = queue1.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty()); 
-         
-         msgs = queue2.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty()); 
-         
-         tx.rollback();
-         
-         msgs = receiver1.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         receiver1.clear();
-         
-         msgs = receiver2.getMessages();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-         
-         receiver2.clear();
-         
-         
-         Message msg5 = CoreMessageFactory.createCoreMessage(5, persistentMessage, null);      
-         MessageReference ref5 = ms.reference(msg5);
-         
-         Message msg6 = CoreMessageFactory.createCoreMessage(6, persistentMessage, null);      
-         MessageReference ref6 = ms.reference(msg6);
-               
-         routed = postOffice.route(ref5, new SimpleCondition("topic1"), null);            
-         assertTrue(routed);
-         routed = postOffice.route(ref6, new SimpleCondition("topic1"), null);            
-         assertTrue(routed);
-         
-         msgs = receiver1.getMessages();
-         assertNotNull(msgs);
-         assertEquals(2, msgs.size());
-         msgRec1 = (Message)msgs.get(0);
-         msgRec2 = (Message)msgs.get(1);
-         assertTrue(msgRec1 == msg5);
-         assertTrue(msgRec2 == msg6);
-         
-         msgs = receiver2.getMessages();
-         assertNotNull(msgs);
-         assertEquals(2, msgs.size());
-         msgRec1 = (Message)msgs.get(0);
-         msgRec2 = (Message)msgs.get(1);
-         assertTrue(msgRec1 == msg5);
-         assertTrue(msgRec2 == msg6);
-         
-         //Acknowledge transactionally
-         
-         tx = tr.createTransaction();
-         
-         receiver1.acknowledge(msgRec1, tx);
-         receiver1.acknowledge(msgRec2, tx);
-         
-         receiver2.acknowledge(msgRec1, tx);
-         receiver2.acknowledge(msgRec2, tx);
-         
-         int deliveringCount = queue1.getDeliveringCount();
-         assertEquals(2, deliveringCount);
-         
-         deliveringCount = queue2.getDeliveringCount();
-         assertEquals(2, deliveringCount);
-         
-         tx.commit();
-         
-         msgs = queue1.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-               
-         receiver1.clear();
-         
-         msgs = queue2.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-               
-         receiver2.clear();
-         
-         Message msg7 = CoreMessageFactory.createCoreMessage(7, persistentMessage, null);      
-         MessageReference ref7 = ms.reference(msg7);
-         
-         Message msg8 = CoreMessageFactory.createCoreMessage(8, persistentMessage, null);      
-         MessageReference ref8 = ms.reference(msg8);
-               
-         routed = postOffice.route(ref7, new SimpleCondition("topic1"), null);            
-         assertTrue(routed);
-         routed = postOffice.route(ref8, new SimpleCondition("topic1"), null);            
-         assertTrue(routed);
-         
-         msgs = receiver1.getMessages();
-         assertNotNull(msgs);
-         assertEquals(2, msgs.size());
-         msgRec1 = (Message)msgs.get(0);
-         msgRec2 = (Message)msgs.get(1);
-         assertTrue(msgRec1 == msg7);
-         assertTrue(msgRec2 == msg8);
-         
-         msgs = receiver2.getMessages();
-         assertNotNull(msgs);
-         assertEquals(2, msgs.size());
-         msgRec1 = (Message)msgs.get(0);
-         msgRec2 = (Message)msgs.get(1);
-         assertTrue(msgRec1 == msg7);
-         assertTrue(msgRec2 == msg8);
-         
-         //Acknowledge transactionally
-         
-         tx = tr.createTransaction();
-         
-         receiver1.acknowledge(msgRec1, tx);
-         receiver1.acknowledge(msgRec2, tx);
-         
-         receiver2.acknowledge(msgRec1, tx);
-         receiver2.acknowledge(msgRec2, tx);
-         
-         deliveringCount = queue1.getDeliveringCount();
-         assertEquals(2, deliveringCount);
-         
-         deliveringCount = queue2.getDeliveringCount();
-         assertEquals(2, deliveringCount);
-         
-         tx.rollback();
-         
-         deliveringCount = queue1.getDeliveringCount();
-         assertEquals(2, deliveringCount);                  
-         
-         receiver1.acknowledge(msgRec1, null);
-         receiver1.acknowledge(msgRec2, null);
-         
-         deliveringCount = queue2.getDeliveringCount();
-         assertEquals(2, deliveringCount);     
-         
-         
-         receiver2.acknowledge(msgRec1, null);
-         receiver2.acknowledge(msgRec2, null);
-         
-         if (checkNoMessageData())
-         {
-            fail("data still in database");
-         }
-      }
-      finally
-      {
-         if (postOffice != null)
-         {
-            postOffice.stop();
-         }         
-      }
-   }
-   
-   protected void assertEquivalent(Binding binding1, Binding binding2)
-   {
-      assertEquals(binding1.getNodeID(), binding2.getNodeID());
-      assertEquals(binding1.getQueue().getName(), binding2.getQueue().getName());
-
-      String selector1 =
-         binding1.getQueue().getFilter() != null ?
-            binding1.getQueue().getFilter().getFilterString() : null;
-
-      String selector2 =
-         binding2.getQueue().getFilter() != null ?
-            binding2.getQueue().getFilter().getFilterString() : null;
-
-      assertEquals(selector1, selector2);
-      assertEquals(binding1.getQueue().getChannelID(), binding2.getQueue().getChannelID());
-      assertEquals(binding1.getQueue().isRecoverable(), binding2.getQueue().isRecoverable());
-   }
-
-   protected void setUp() throws Exception
-   {
-      super.setUp();
-
-   }
-
-   protected void tearDown() throws Exception
-   {
-      super.tearDown();
-   }
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-
-}
-

Added: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/PostOfficeTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/PostOfficeTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/PostOfficeTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,1284 @@
+/*
+  * 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.postoffice;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.jboss.messaging.core.contract.Binding;
+import org.jboss.messaging.core.contract.Condition;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.PostOffice;
+import org.jboss.messaging.core.contract.Queue;
+import org.jboss.messaging.core.impl.MessagingQueue;
+import org.jboss.messaging.core.impl.tx.Transaction;
+import org.jboss.test.messaging.core.PostOfficeTestBase;
+import org.jboss.test.messaging.core.SimpleCondition;
+import org.jboss.test.messaging.core.SimpleFilter;
+import org.jboss.test.messaging.core.SimpleReceiver;
+import org.jboss.test.messaging.util.CoreMessageFactory;
+
+/**
+ * 
+ * A PostOfficeTest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 2386 $</tt>
+ *
+ * $Id: DefaultPostOfficeTest.java 2386 2007-02-21 18:07:44Z timfox $
+ *
+ */
+public class PostOfficeTest extends PostOfficeTestBase
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+
+   // Constructors --------------------------------------------------
+
+   public PostOfficeTest(String name)
+   {
+      super(name);
+   }
+
+   // Public --------------------------------------------------------
+
+   public final void testBindUnbind() throws Throwable
+   {
+      PostOffice office1 = null;
+      
+      PostOffice office2 = null;
+      
+      PostOffice office3 = null;
+      
+      try
+      {             
+         office1 = createNonClusteredPostOffice();
+         
+         //Bind one durable
+             
+         MessagingQueue queue1 =
+            new MessagingQueue(1, "durableQueue", channelIDManager.getID(), ms, pm, true, 1, null, false, false);
+         queue1.activate();
+         
+         Condition condition1 = new SimpleCondition("condition1");
+                  
+         office1.addBinding(new Binding(condition1, queue1), false);
+         
+         //Binding twice with the same name should fail      
+         try
+         {
+            office1.addBinding(new Binding(condition1, queue1), false);
+            fail();
+         }
+         catch (IllegalArgumentException e)
+         {
+            //Ok
+         }
+         
+         //Can't bind a queue from another node
+         
+         try
+         {
+         
+	         MessagingQueue queuexx =
+	            new MessagingQueue(777, "durableQueue", channelIDManager.getID(), ms, pm, true, 1, null, false, false);
+	         queuexx.activate();
+	         office1.addBinding(new Binding(condition1, queuexx), false);
+            fail();
+         }
+         catch (IllegalArgumentException e)
+         {
+            //Ok
+         }
+         
+               
+         //Bind one non durable
+         MessagingQueue queue2 =
+            new MessagingQueue(1, "nonDurableQueue", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue2.activate();
+         
+         Condition condition2 = new SimpleCondition("condition2");         
+         
+         office1.addBinding(new Binding(condition2, queue2), false);
+         
+         //Check they're there
+         
+         Collection queues = office1.getQueuesForCondition(condition1, true);
+         assertNotNull(queues);
+         assertEquals(1, queues.size());
+         Queue rqueue1 = (Queue)queues.iterator().next();
+         assertEquals(queue1, rqueue1);
+         
+         queues = office1.getQueuesForCondition(condition2, true);
+         assertNotNull(queues);
+         assertEquals(1, queues.size());
+         Queue rqueue2 = (Queue)queues.iterator().next();
+         assertEquals(queue2, rqueue2);
+         
+         
+         
+         office1.stop();
+         
+         //Throw away the office and create another
+         office2 = createNonClusteredPostOffice();
+         
+         //Only one binding should be there
+         queues = office2.getQueuesForCondition(condition1, true);
+         assertNotNull(queues);
+         assertEquals(1, queues.size());
+         rqueue1 = (Queue)queues.iterator().next();
+         assertEquals(queue1, rqueue1);
+         
+         queues = office2.getQueuesForCondition(condition2, true);
+         assertNotNull(queues);
+         assertTrue(queues.isEmpty());
+         
+         //Unbind the binding
+         office2.removeBinding(queue1.getName(), false);
+         
+         
+         //Make sure no longer there
+         queues = office2.getQueuesForCondition(condition1, true);
+         assertNotNull(queues);
+         assertTrue(queues.isEmpty());
+         
+         queues = office2.getQueuesForCondition(condition2, true);
+         assertNotNull(queues);
+         assertTrue(queues.isEmpty());
+         
+         office2.stop();
+         
+         //Throw away office and start another
+         office3 = createNonClusteredPostOffice();
+         
+         //Make sure not there
+         queues = office3.getQueuesForCondition(condition1, true);
+         assertNotNull(queues);
+         assertTrue(queues.isEmpty());
+         
+         queues = office3.getQueuesForCondition(condition2, true);
+         assertNotNull(queues);
+         assertTrue(queues.isEmpty());
+                  
+      }
+      finally
+      {
+         if (office1 != null)
+         {
+            office1.stop();
+         }
+         
+         if (office2 != null)
+         {
+            office2.stop();
+         }
+         
+         if (office3 != null)
+         {
+            office2.stop();
+         }
+         
+         if (checkNoBindingData())
+         {
+            fail("Binding data still in database");
+         }
+      }
+            
+   }
+   
+   public final void testGetQueuesForCondition() throws Throwable
+   {
+      PostOffice office = null;
+      
+      try
+      {      
+         office = createNonClusteredPostOffice();
+         
+         Condition condition1 = new SimpleCondition("condition1");
+         
+         MessagingQueue queue1 = new MessagingQueue(1, "queue1", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue1.activate();
+         
+         office.addBinding(new Binding(condition1, queue1), false);
+         
+         MessagingQueue queue2 = new MessagingQueue(1, "queue2", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue2.activate();
+         
+         office.addBinding(new Binding(condition1, queue2), false);
+         
+         MessagingQueue queue3 = new MessagingQueue(1, "queue3", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue3.activate();
+         
+         office.addBinding(new Binding(condition1, queue3), false);
+         
+         MessagingQueue queue4 = new MessagingQueue(1, "queue4", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue4.activate();
+         
+         office.addBinding(new Binding(condition1, queue4), false);
+         
+         MessagingQueue queue5 = new MessagingQueue(1, "queue5", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue5.activate();
+         
+         Condition condition2 = new SimpleCondition("condition2");         
+         
+         office.addBinding(new Binding(condition2, queue5), false);
+         
+         MessagingQueue queue6 = new MessagingQueue(1, "queue6", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue6.activate();
+         
+         office.addBinding(new Binding(condition2, queue6), false);
+         
+         MessagingQueue queue7 = new MessagingQueue(1, "queue7", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue7.activate();
+         
+         office.addBinding(new Binding(condition2, queue7), false);
+         
+         MessagingQueue queue8 = new MessagingQueue(1, "queue8", channelIDManager.getID(), ms, pm,  false, -1, null, false, false);
+         queue8.activate();
+         
+         office.addBinding(new Binding(condition2, queue8), false);
+                  
+         Collection queues = office.getQueuesForCondition(new SimpleCondition("dummy"), true);
+         assertNotNull(queues);
+         assertTrue(queues.isEmpty());
+                           
+         //We don't match on substrings
+         queues = office.getQueuesForCondition(new SimpleCondition("condition123"), true);
+         assertNotNull(queues);
+         assertTrue(queues.isEmpty());
+         
+         //We don't currently support hierarchies
+         queues = office.getQueuesForCondition(new SimpleCondition("condition1.subcondition"), true);
+         assertNotNull(queues);
+         assertTrue(queues.isEmpty());
+         
+         //Lookup the queues
+         
+         queues = office.getQueuesForCondition(condition1, true);
+         assertNotNull(queues);
+         assertEquals(4, queues.size());
+         
+         assertTrue(queues.contains(queue1));
+         assertTrue(queues.contains(queue2));
+         assertTrue(queues.contains(queue3));
+         assertTrue(queues.contains(queue4));
+         
+         queues = office.getQueuesForCondition(condition2, true);
+         assertNotNull(queues);
+         assertEquals(4, queues.size());
+         
+         assertTrue(queues.contains(queue5));
+         assertTrue(queues.contains(queue6));
+         assertTrue(queues.contains(queue7));
+         assertTrue(queues.contains(queue8));
+         
+         //Lookup should work on new instance too
+         
+         queues = office.getQueuesForCondition(new SimpleCondition("condition1"), true);
+         assertNotNull(queues);
+         assertEquals(4, queues.size());
+         
+         assertTrue(queues.contains(queue1));
+         assertTrue(queues.contains(queue2));
+         assertTrue(queues.contains(queue3));
+         assertTrue(queues.contains(queue4));
+         
+         queues = office.getQueuesForCondition(new SimpleCondition("condition2"), true);
+         assertNotNull(queues);
+         assertEquals(4, queues.size());
+         
+         assertTrue(queues.contains(queue5));
+         assertTrue(queues.contains(queue6));
+         assertTrue(queues.contains(queue7));
+         assertTrue(queues.contains(queue8));
+         
+      }
+      finally
+      {
+         if (office != null)
+         {
+            office.stop();
+         }
+         
+         if (checkNoBindingData())
+         {
+            fail("Binding data still in database");
+         }
+      }
+         
+   }
+   
+   public void testGetBindingForQueueName() throws Throwable
+   {   	
+      PostOffice office = null;
+      
+      try
+      {      
+         office = createNonClusteredPostOffice();
+                  
+         Condition condition1 = new SimpleCondition("condition1");  
+         
+         MessagingQueue queue1 = new MessagingQueue(1, "queue1", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         office.addBinding(new Binding(condition1, queue1), false);
+                         
+         MessagingQueue queue2 = new MessagingQueue(1, "queue2", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         office.addBinding(new Binding(condition1, queue2), false);
+         
+         Condition condition2 = new SimpleCondition("condition2");  
+                  
+         MessagingQueue queue3 = new MessagingQueue(1, "queue3", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         office.addBinding(new Binding(condition2, queue3), false);
+         
+         Binding b1 = office.getBindingForQueueName("queue1");
+         assertNotNull(b1);
+         assertEquals(queue1, b1.queue);
+         assertEquals(condition1, b1.condition);
+         
+         Binding b2 = office.getBindingForQueueName("queue2");
+         assertNotNull(b2);
+         assertEquals(queue2, b2.queue);
+         assertEquals(condition1, b2.condition);
+         
+         Binding b3 = office.getBindingForQueueName("queue3");
+         assertNotNull(b3);
+         assertEquals(queue3, b3.queue);
+         assertEquals(condition2, b3.condition);
+         
+         office.removeBinding("queue1", false);
+         
+         b1 = office.getBindingForQueueName("queue1");
+         assertNull(b1);
+
+         b2 = office.getBindingForQueueName("queue2");
+         assertNotNull(b2);
+         assertEquals(queue2, b2.queue);
+         assertEquals(condition1, b2.condition);
+         
+         b3 = office.getBindingForQueueName("queue3");
+         assertNotNull(b3);
+         assertEquals(queue3, b3.queue);
+         assertEquals(condition2, b3.condition);
+         
+         office.removeBinding("queue2", false);
+         office.removeBinding("queue3", false);
+         
+         b1 = office.getBindingForQueueName("queue1");
+         assertNull(b1);
+
+         b2 = office.getBindingForQueueName("queue2");
+         assertNull(b2);
+ 
+         b3 = office.getBindingForQueueName("queue3");
+         assertNull(b3);                     
+      }
+      finally
+      {
+         if (office != null)
+         {
+            office.stop();
+         }
+         
+         if (checkNoBindingData())
+         {
+            fail("Binding data still in database");
+         }
+      }
+         
+   }
+   
+   public void testGetBindingForChannelID() throws Throwable
+   {   	
+      PostOffice office = null;
+      
+      try
+      {      
+         office = createNonClusteredPostOffice();
+                  
+         Condition condition1 = new SimpleCondition("condition1");  
+         
+         MessagingQueue queue1 = new MessagingQueue(1, "queue1", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         office.addBinding(new Binding(condition1, queue1), false);
+                         
+         MessagingQueue queue2 = new MessagingQueue(1, "queue2", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         office.addBinding(new Binding(condition1, queue2), false);
+         
+         Condition condition2 = new SimpleCondition("condition2");  
+                  
+         MessagingQueue queue3 = new MessagingQueue(1, "queue3", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         office.addBinding(new Binding(condition2, queue3), false);
+         
+         Binding b1 = office.getBindingForChannelID(queue1.getChannelID());
+         assertNotNull(b1);
+         assertEquals(queue1, b1.queue);
+         assertEquals(condition1, b1.condition);
+         
+         Binding b2 = office.getBindingForChannelID(queue2.getChannelID());
+         assertNotNull(b2);
+         assertEquals(queue2, b2.queue);
+         assertEquals(condition1, b2.condition);
+         
+         Binding b3 = office.getBindingForChannelID(queue3.getChannelID());
+         assertNotNull(b3);
+         assertEquals(queue3, b3.queue);
+         assertEquals(condition2, b3.condition);
+         
+         office.removeBinding("queue1", false);
+         
+         b1 = office.getBindingForChannelID(queue1.getChannelID());
+         assertNull(b1);
+
+         b2 =office.getBindingForChannelID(queue2.getChannelID());
+         assertNotNull(b2);
+         assertEquals(queue2, b2.queue);
+         assertEquals(condition1, b2.condition);
+         
+         b3 = office.getBindingForChannelID(queue3.getChannelID());
+         assertNotNull(b3);
+         assertEquals(queue3, b3.queue);
+         assertEquals(condition2, b3.condition);
+         
+         office.removeBinding("queue2", false);
+         office.removeBinding("queue3", false);
+         
+         b1 = office.getBindingForChannelID(queue1.getChannelID());
+         assertNull(b1);
+
+         b2 = office.getBindingForChannelID(queue2.getChannelID());
+         assertNull(b2);
+ 
+         b3 = office.getBindingForChannelID(queue3.getChannelID());
+         assertNull(b3);                     
+      }
+      finally
+      {
+         if (office != null)
+         {
+            office.stop();
+         }
+         
+         if (checkNoBindingData())
+         {
+            fail("Binding data still in database");
+         }
+      }
+         
+   }
+
+   public void testRouteNonPersistentWithFilter() throws Throwable
+   {
+      routeWithFilter(false);
+   }
+   
+   public void testRoutePersistentWithFilter() throws Throwable
+   {
+      routeWithFilter(true);
+   }
+   
+   public final void testRoutePersistent() throws Throwable
+   {
+      route(true);
+   }
+   
+   public final void testRouteNonPersistent() throws Throwable
+   {
+      route(false);
+   }
+   
+   public final void testRouteTransactionalPersistent() throws Throwable
+   {
+      routeTransactional(true);
+   }
+   
+   public final void testRouteTransactionalNonPersistent() throws Throwable
+   {
+      routeTransactional(false);
+   }
+         
+   public final void testRouteInactive() throws Throwable
+   {
+      PostOffice postOffice = null;
+      
+      try
+      {      
+         postOffice = createNonClusteredPostOffice();
+         
+         Condition condition1 = new SimpleCondition("topic1");
+         
+         MessagingQueue queue1 =  new MessagingQueue(1, "queue1", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue1.activate();
+         
+         postOffice.addBinding(new Binding(condition1, queue1), false);
+         
+         MessagingQueue queue2 =  new MessagingQueue(1, "queue2", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue2.activate();
+         
+         postOffice.addBinding(new Binding(condition1, queue2), false);
+         
+         MessagingQueue queue3 = new MessagingQueue(1, "queue3", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue3.activate();
+         
+         postOffice.addBinding(new Binding(condition1, queue3), false);
+         
+         MessagingQueue queue4 = new MessagingQueue(1, "queue4", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue4.activate();
+         
+         Condition condition2 = new SimpleCondition("topic2");
+         
+         
+         postOffice.addBinding(new Binding(condition2, queue4), false);
+         
+         MessagingQueue queue5 = new MessagingQueue(1, "queue5", channelIDManager.getID(), ms, pm, false,-1, null, false, false);
+         queue5.activate();
+         
+         postOffice.addBinding(new Binding(condition2, queue5), false);
+         
+         MessagingQueue queue6 = new MessagingQueue(1, "queue6", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue6.activate();
+         
+         postOffice.addBinding(new Binding(condition2, queue6), false);
+      
+         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+         queue1.getLocalDistributor().add(receiver1);
+         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+         queue2.getLocalDistributor().add(receiver2);
+         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+         queue3.getLocalDistributor().add(receiver3);
+         SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+         queue4.getLocalDistributor().add(receiver4);
+         SimpleReceiver receiver5 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+         queue5.getLocalDistributor().add(receiver5);
+         SimpleReceiver receiver6 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+         queue6.getLocalDistributor().add(receiver6);
+         
+         queue1.deactivate();
+         queue2.deactivate();
+         queue5.deactivate();
+         queue6.deactivate();
+         
+         assertFalse(queue1.isActive());      
+         assertFalse(queue2.isActive());
+         assertFalse(queue5.isActive());
+         assertFalse(queue6.isActive()); 
+         assertTrue(queue3.isActive());
+         assertTrue(queue4.isActive());      
+         
+         Message msg1 = CoreMessageFactory.createCoreMessage(1);      
+         MessageReference ref1 = ms.reference(msg1);
+         
+         boolean routed = postOffice.route(ref1, condition1, null);      
+         assertTrue(routed);
+         
+         List msgs = receiver1.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = receiver2.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = receiver3.getMessages();
+         assertNotNull(msgs);
+         assertEquals(1, msgs.size());
+         Message msgRec = (Message)msgs.get(0);
+         assertTrue(msg1 == msgRec);
+         receiver3.acknowledge(msgRec, null);
+         msgs = queue3.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());  
+         
+         msgs = receiver4.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = receiver5.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = receiver6.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         receiver3.clear();
+                     
+         Message msg2 = CoreMessageFactory.createCoreMessage(2);      
+         MessageReference ref2 = ms.reference(msg2);
+         
+         routed = postOffice.route(ref2, condition2, null);      
+         assertTrue(routed);
+         
+         msgs = receiver1.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = receiver2.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = receiver3.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());      
+         
+         msgs = receiver4.getMessages();
+         assertNotNull(msgs);
+         assertEquals(1, msgs.size());
+         msgRec = (Message)msgs.get(0);
+         assertTrue(msg2 == msgRec);
+         receiver4.acknowledge(msgRec, null);
+         msgs = queue4.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());  
+         
+         msgs = receiver5.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = receiver6.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         if (checkNoMessageData())
+         {
+            fail("data still in database");
+         }
+      }
+      finally
+      {
+         if (postOffice != null)
+         {
+            postOffice.stop();
+         }
+         
+      }
+   
+   }
+
+   public final void testRouteNoQueue() throws Throwable
+   {
+      PostOffice postOffice = null;
+      
+      try
+      {      
+         postOffice = createNonClusteredPostOffice();
+         
+         MessagingQueue queue1 = new MessagingQueue(1, "queue1", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue1.activate();
+         
+         postOffice.addBinding(new Binding(new SimpleCondition("condition1"), queue1), false);
+              
+         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
+         
+         queue1.getLocalDistributor().add(receiver1);
+   
+         assertTrue(queue1.isActive());
+   
+         Message msg1 = CoreMessageFactory.createCoreMessage(1);      
+         
+         MessageReference ref1 = ms.reference(msg1);
+         
+         boolean routed = postOffice.route(ref1, new SimpleCondition("this won't match anything"), null);
+         
+         assertFalse(routed);
+               
+         List msgs = receiver1.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());  
+         
+         if (checkNoMessageData())
+         {
+            fail("data still in database");
+         }
+         
+      }
+      finally
+      {
+         if (postOffice != null)
+         {
+            postOffice.stop();
+         }
+         
+      }
+   }
+   
+   
+   
+   // Package protected ---------------------------------------------
+
+   // Protected -----------------------------------------------------
+   
+   protected void routeWithFilter(boolean persistentMessage) throws Throwable
+   {
+      PostOffice postOffice = null;
+      
+      try
+      {      
+         postOffice = createNonClusteredPostOffice();
+         
+         SimpleFilter filter = new SimpleFilter(2);
+         
+         Condition condition1 = new SimpleCondition("topic1");
+      
+         MessagingQueue queue1 = new MessagingQueue(1, "queue1", channelIDManager.getID(), ms, pm, false, -1, filter, false, false);
+         queue1.activate();
+         
+         postOffice.addBinding(new Binding(condition1, queue1), false);
+         
+         MessagingQueue queue2 = new MessagingQueue(1, "queue2", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue2.activate();
+         
+         postOffice.addBinding(new Binding(condition1, queue2), false);
+         
+         MessagingQueue queue3 = new MessagingQueue(1, "queue3", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue3.activate();
+         
+         postOffice.addBinding(new Binding(condition1, queue3), false);
+         
+         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+         queue1.getLocalDistributor().add(receiver1);
+         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+         queue2.getLocalDistributor().add(receiver2);
+         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
+         queue3.getLocalDistributor().add(receiver3);
+         
+         Message msg1 = CoreMessageFactory.createCoreMessage(1);      
+         MessageReference ref1 = ms.reference(msg1);         
+         boolean routed = postOffice.route(ref1, condition1, null);      
+         assertTrue(routed);
+         Message msg2 = CoreMessageFactory.createCoreMessage(2);      
+         MessageReference ref2 = ms.reference(msg2);         
+         routed = postOffice.route(ref2, condition1, null);      
+         assertTrue(routed);
+         Message msg3 = CoreMessageFactory.createCoreMessage(3);      
+         MessageReference ref3 = ms.reference(msg3);         
+         routed = postOffice.route(ref3, condition1, null);      
+         assertTrue(routed);
+         
+         List msgs = receiver1.getMessages();
+         assertNotNull(msgs);           
+         assertEquals(1, msgs.size());                  
+         Message msgRec = (Message)msgs.get(0);
+         assertTrue(msg2 == msgRec);
+         receiver1.acknowledge(msgRec, null);
+         msgs = queue1.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());  
+         
+         msgs = receiver2.getMessages();
+         assertNotNull(msgs);
+         assertEquals(3, msgs.size());
+         Message msgRec1 = (Message)msgs.get(0);
+         assertTrue(msg1 == msgRec1);
+         Message msgRec2 = (Message)msgs.get(1);
+         assertTrue(msg2 == msgRec2);
+         Message msgRec3 = (Message)msgs.get(2);
+         assertTrue(msg3 == msgRec3);
+          
+         receiver2.acknowledge(msgRec1, null);
+         receiver2.acknowledge(msgRec2, null);
+         receiver2.acknowledge(msgRec3, null);
+         msgs = queue2.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());  
+         
+         msgs = receiver3.getMessages();
+         assertNotNull(msgs);
+         assertEquals(3, msgs.size());
+         msgRec1 = (Message)msgs.get(0);
+         assertTrue(msg1 == msgRec1);
+         msgRec2 = (Message)msgs.get(1);
+         assertTrue(msg2 == msgRec2);
+         msgRec3 = (Message)msgs.get(2);
+         assertTrue(msg3 == msgRec3);
+          
+         receiver3.acknowledge(msgRec1, null);
+         receiver3.acknowledge(msgRec2, null);
+         receiver3.acknowledge(msgRec3, null);
+         msgs = queue3.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty()); 
+         
+         if (checkNoMessageData())
+         {
+            fail("data still in database");
+         }
+         
+      }
+      finally
+      {
+         if (postOffice != null)
+         {
+            postOffice.stop();
+         }
+        
+      }
+   }
+   
+   protected void route(boolean persistentMessage) throws Throwable
+   {
+      PostOffice postOffice = null;
+      
+      try
+      {      
+         postOffice = createNonClusteredPostOffice();
+      
+         Condition condition1 = new SimpleCondition("topic1");
+         
+         MessagingQueue queue1 = new MessagingQueue(1, "queue1", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue1.activate();
+         
+         postOffice.addBinding(new Binding(condition1, queue1), false);
+         
+         MessagingQueue queue2 = new MessagingQueue(1, "queue2", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue2.activate();
+         
+         postOffice.addBinding(new Binding(condition1, queue2), false);
+         
+         MessagingQueue queue3 = new MessagingQueue(1, "queue3", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue3.activate();
+         
+         postOffice.addBinding(new Binding(condition1, queue3), false);
+         
+         MessagingQueue queue4 = new MessagingQueue(1, "queue4", channelIDManager.getID(), ms, pm, true, -1, null, false, false);
+         queue4.activate();
+         
+         Condition condition2 = new SimpleCondition("topic2");
+         
+         postOffice.addBinding(new Binding(condition2, queue4), false);
+         
+         MessagingQueue queue5 = new MessagingQueue(1, "queue5", channelIDManager.getID(), ms, pm, true, -1, null, false, false);
+         queue5.activate();
+         
+         postOffice.addBinding(new Binding(condition2, queue5), false);
+         
+         MessagingQueue queue6 = new MessagingQueue(1, "queue6", channelIDManager.getID(), ms, pm, true, -1, null, false, false);
+         queue6.activate();
+         
+         postOffice.addBinding(new Binding(condition2, queue6), false);
+      
+         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
+         queue1.getLocalDistributor().add(receiver1);
+         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
+         queue2.getLocalDistributor().add(receiver2);
+         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
+         queue3.getLocalDistributor().add(receiver3);
+         SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
+         queue4.getLocalDistributor().add(receiver4);
+         SimpleReceiver receiver5 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
+         queue5.getLocalDistributor().add(receiver5);
+         SimpleReceiver receiver6 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
+         queue6.getLocalDistributor().add(receiver6);
+         
+         assertTrue(queue1.isActive());      
+         assertTrue(queue2.isActive());
+         assertTrue(queue3.isActive());      
+         assertTrue(queue4.isActive());
+         assertTrue(queue5.isActive());      
+         assertTrue(queue6.isActive());
+         
+         Message msg1 = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
+         MessageReference ref1 = ms.reference(msg1);
+         
+         boolean routed = postOffice.route(ref1, condition1, null);      
+         assertTrue(routed);
+         
+         List msgs = receiver1.getMessages();
+         assertNotNull(msgs);
+         assertEquals(1, msgs.size());
+         Message msgRec = (Message)msgs.get(0);
+         assertTrue(msg1 == msgRec);
+         receiver1.acknowledge(msgRec, null);
+         msgs = queue1.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = receiver2.getMessages();
+         assertNotNull(msgs);
+         assertEquals(1, msgs.size());
+         msgRec = (Message)msgs.get(0);
+         assertTrue(msg1 == msgRec);
+         receiver2.acknowledge(msgRec, null);
+         msgs = queue2.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = receiver3.getMessages();
+         assertNotNull(msgs);
+         assertEquals(1, msgs.size());
+         msgRec = (Message)msgs.get(0);
+         assertTrue(msg1 == msgRec);
+         receiver3.acknowledge(msgRec, null);
+         msgs = queue3.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = receiver4.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = receiver5.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = receiver6.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         receiver1.clear();
+         receiver2.clear();
+         receiver3.clear();
+         
+         
+         Message msg2 = CoreMessageFactory.createCoreMessage(2, persistentMessage, null);      
+         MessageReference ref2 = ms.reference(msg2);
+         
+         routed = postOffice.route(ref2, condition2, null);      
+         assertTrue(routed);
+         
+         msgs = receiver4.getMessages();
+         assertNotNull(msgs);
+         assertEquals(1, msgs.size());
+         msgRec = (Message)msgs.get(0);
+         assertTrue(msg2 == msgRec);
+         receiver4.acknowledge(msgRec, null);
+         msgs = queue4.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = receiver5.getMessages();
+         assertNotNull(msgs);
+         assertEquals(1, msgs.size());
+         msgRec = (Message)msgs.get(0);
+         assertTrue(msg2 == msgRec);
+         receiver5.acknowledge(msgRec, null);
+         msgs = queue5.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = receiver6.getMessages();
+         assertNotNull(msgs);
+         assertEquals(1, msgs.size());
+         msgRec = (Message)msgs.get(0);
+         assertTrue(msg2 == msgRec);
+         receiver6.acknowledge(msgRec, null);
+         msgs = queue6.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());    
+         
+         msgs = receiver1.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = receiver2.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = receiver3.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+      }
+      finally
+      {
+         if (postOffice != null)
+         {
+            postOffice.stop();
+         }
+         
+         if (checkNoMessageData())
+         {
+            fail("data still in database");
+         }
+      }
+   }
+   
+   protected void routeTransactional(boolean persistentMessage) throws Throwable
+   {
+      PostOffice postOffice = null;
+      
+      try
+      {      
+         postOffice = createNonClusteredPostOffice();
+         
+         Condition condition1 = new SimpleCondition("topic1");
+      
+         MessagingQueue queue1 = new MessagingQueue(1, "queue1", channelIDManager.getID(), ms, pm, false, -1, null, false, false);
+         queue1.activate();
+         
+         postOffice.addBinding(new Binding(condition1, queue1), false);
+         
+         MessagingQueue queue2 = new MessagingQueue(1, "queue2", channelIDManager.getID(), ms, pm, true,-1, null, false, false);
+         queue2.activate();
+         
+         postOffice.addBinding(new Binding(condition1, queue2), false);
+          
+         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
+         queue1.getLocalDistributor().add(receiver1);
+
+         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);;
+         queue2.getLocalDistributor().add(receiver2);
+   
+         assertTrue(queue1.isActive());
+         assertTrue(queue2.isActive());
+   
+         Message msg1 = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
+         MessageReference ref1 = ms.reference(msg1);
+         
+         Message msg2 = CoreMessageFactory.createCoreMessage(2, persistentMessage, null);      
+         MessageReference ref2 = ms.reference(msg2);
+         
+         Transaction tx = tr.createTransaction();
+         
+         boolean routed = postOffice.route(ref1, condition1, tx);            
+         assertTrue(routed);
+         routed = postOffice.route(ref2, condition1, tx);            
+         assertTrue(routed);
+               
+         List msgs = queue1.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         msgs = queue2.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         tx.commit();
+         
+         msgs = receiver1.getMessages();
+         assertNotNull(msgs);
+         assertEquals(2, msgs.size());
+         Message msgRec1 = (Message)msgs.get(0);
+         Message msgRec2 = (Message)msgs.get(1);
+         assertTrue(msgRec1 == msg1);
+         assertTrue(msgRec2 == msg2);
+         
+         msgs = receiver2.getMessages();
+         assertNotNull(msgs);
+         assertEquals(2, msgs.size());
+         msgRec1 = (Message)msgs.get(0);
+         msgRec2 = (Message)msgs.get(1);
+         assertTrue(msgRec1 == msg1);
+         assertTrue(msgRec2 == msg2);
+         
+         //Acknowledge
+         receiver1.acknowledge(msgRec1, null);
+         receiver1.acknowledge(msgRec2, null);
+         
+         receiver2.acknowledge(msgRec1, null);
+         receiver2.acknowledge(msgRec2, null);
+   
+         msgs = queue1.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty()); 
+         
+         receiver1.clear();
+         
+         msgs = queue2.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty()); 
+         
+         receiver2.clear();
+              
+         Message msg3 = CoreMessageFactory.createCoreMessage(3, persistentMessage, null);      
+         MessageReference ref3 = ms.reference(msg3);
+         
+         Message msg4 = CoreMessageFactory.createCoreMessage(4, persistentMessage, null);      
+         MessageReference ref4 = ms.reference(msg4);
+         
+         tx = tr.createTransaction();
+         
+         routed = postOffice.route(ref3, condition1, tx);            
+         assertTrue(routed);
+         routed = postOffice.route(ref4, condition1, tx);            
+         assertTrue(routed);
+               
+         msgs = queue1.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty()); 
+         
+         msgs = queue2.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty()); 
+         
+         tx.rollback();
+         
+         msgs = receiver1.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         receiver1.clear();
+         
+         msgs = receiver2.getMessages();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+         
+         receiver2.clear();
+         
+         
+         Message msg5 = CoreMessageFactory.createCoreMessage(5, persistentMessage, null);      
+         MessageReference ref5 = ms.reference(msg5);
+         
+         Message msg6 = CoreMessageFactory.createCoreMessage(6, persistentMessage, null);      
+         MessageReference ref6 = ms.reference(msg6);
+               
+         routed = postOffice.route(ref5, new SimpleCondition("topic1"), null);            
+         assertTrue(routed);
+         routed = postOffice.route(ref6, new SimpleCondition("topic1"), null);            
+         assertTrue(routed);
+         
+         msgs = receiver1.getMessages();
+         assertNotNull(msgs);
+         assertEquals(2, msgs.size());
+         msgRec1 = (Message)msgs.get(0);
+         msgRec2 = (Message)msgs.get(1);
+         assertTrue(msgRec1 == msg5);
+         assertTrue(msgRec2 == msg6);
+         
+         msgs = receiver2.getMessages();
+         assertNotNull(msgs);
+         assertEquals(2, msgs.size());
+         msgRec1 = (Message)msgs.get(0);
+         msgRec2 = (Message)msgs.get(1);
+         assertTrue(msgRec1 == msg5);
+         assertTrue(msgRec2 == msg6);
+         
+         //Acknowledge transactionally
+         
+         tx = tr.createTransaction();
+         
+         receiver1.acknowledge(msgRec1, tx);
+         receiver1.acknowledge(msgRec2, tx);
+         
+         receiver2.acknowledge(msgRec1, tx);
+         receiver2.acknowledge(msgRec2, tx);
+         
+         int deliveringCount = queue1.getDeliveringCount();
+         assertEquals(2, deliveringCount);
+         
+         deliveringCount = queue2.getDeliveringCount();
+         assertEquals(2, deliveringCount);
+         
+         tx.commit();
+         
+         msgs = queue1.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+               
+         receiver1.clear();
+         
+         msgs = queue2.browse(null);
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+               
+         receiver2.clear();
+         
+         Message msg7 = CoreMessageFactory.createCoreMessage(7, persistentMessage, null);      
+         MessageReference ref7 = ms.reference(msg7);
+         
+         Message msg8 = CoreMessageFactory.createCoreMessage(8, persistentMessage, null);      
+         MessageReference ref8 = ms.reference(msg8);
+               
+         routed = postOffice.route(ref7, new SimpleCondition("topic1"), null);            
+         assertTrue(routed);
+         routed = postOffice.route(ref8, new SimpleCondition("topic1"), null);            
+         assertTrue(routed);
+         
+         msgs = receiver1.getMessages();
+         assertNotNull(msgs);
+         assertEquals(2, msgs.size());
+         msgRec1 = (Message)msgs.get(0);
+         msgRec2 = (Message)msgs.get(1);
+         assertTrue(msgRec1 == msg7);
+         assertTrue(msgRec2 == msg8);
+         
+         msgs = receiver2.getMessages();
+         assertNotNull(msgs);
+         assertEquals(2, msgs.size());
+         msgRec1 = (Message)msgs.get(0);
+         msgRec2 = (Message)msgs.get(1);
+         assertTrue(msgRec1 == msg7);
+         assertTrue(msgRec2 == msg8);
+         
+         //Acknowledge transactionally
+         
+         tx = tr.createTransaction();
+         
+         receiver1.acknowledge(msgRec1, tx);
+         receiver1.acknowledge(msgRec2, tx);
+         
+         receiver2.acknowledge(msgRec1, tx);
+         receiver2.acknowledge(msgRec2, tx);
+         
+         deliveringCount = queue1.getDeliveringCount();
+         assertEquals(2, deliveringCount);
+         
+         deliveringCount = queue2.getDeliveringCount();
+         assertEquals(2, deliveringCount);
+         
+         tx.rollback();
+         
+         deliveringCount = queue1.getDeliveringCount();
+         assertEquals(2, deliveringCount);                  
+         
+         receiver1.acknowledge(msgRec1, null);
+         receiver1.acknowledge(msgRec2, null);
+         
+         deliveringCount = queue2.getDeliveringCount();
+         assertEquals(2, deliveringCount);     
+         
+         
+         receiver2.acknowledge(msgRec1, null);
+         receiver2.acknowledge(msgRec2, null);
+         
+         if (checkNoMessageData())
+         {
+            fail("data still in database");
+         }
+      }
+      finally
+      {
+         if (postOffice != null)
+         {
+            postOffice.stop();
+         }         
+      }
+   }
+
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+
+   }
+
+   protected void tearDown() throws Exception
+   {
+      super.tearDown();
+   }
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+
+}
+

Copied: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/SimpleJChannelFactory.java (from rev 2781, trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/SimpleJChannelFactory.java)
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/SimpleJChannelFactory.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/SimpleJChannelFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -0,0 +1,97 @@
+/*
+   * 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.postoffice;
+
+import org.jgroups.JChannel;
+import org.jboss.messaging.core.contract.JChannelFactory;
+
+/**
+ * A JChannelFactory that will use String JChannel configurations to create JChannel instances.
+ *
+ * @author <a href="mailto:clebert.suconic at jboss.org">Clebert Suconic</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ */
+public class SimpleJChannelFactory implements JChannelFactory
+{
+   // Constants ------------------------------------------------------------------------------------
+
+   // Static ---------------------------------------------------------------------------------------
+
+   // Attributes -----------------------------------------------------------------------------------
+
+   String asyncConfig;
+   String syncConfig;
+
+   // Constructors ---------------------------------------------------------------------------------
+
+   public SimpleJChannelFactory(String syncConfig, String asyncConfig)
+   {
+      this.syncConfig = syncConfig;
+      this.asyncConfig = asyncConfig;
+   }
+
+   // JChannelFactory ------------------------------------------------------------------------------
+
+   public JChannel createSyncChannel() throws Exception
+   {
+      return new JChannel(syncConfig);
+   }
+
+   public JChannel createASyncChannel() throws Exception
+   {
+      return new JChannel(asyncConfig);
+   }
+
+   // Public ---------------------------------------------------------------------------------------
+
+   public String getAsyncConfig()
+   {
+      return asyncConfig;
+   }
+
+   public void setAsyncConfig(String asyncConfig)
+   {
+      this.asyncConfig = asyncConfig;
+   }
+
+   public String getSyncConfig()
+   {
+      return syncConfig;
+   }
+
+   public void setSyncConfig(String syncConfig)
+   {
+      this.syncConfig = syncConfig;
+   }
+
+   // Package protected ----------------------------------------------------------------------------
+
+   // Protected ------------------------------------------------------------------------------------
+
+   // Private --------------------------------------------------------------------------------------
+
+   // Inner classes --------------------------------------------------------------------------------
+
+}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/ClusteredPersistenceServiceConfigFileJChannelFactory.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/ClusteredPersistenceServiceConfigFileJChannelFactory.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/ClusteredPersistenceServiceConfigFileJChannelFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,194 +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.plugin.postoffice.cluster;
-
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.plugin.postoffice.cluster.jchannelfactory.JChannelFactory;
-import org.jboss.messaging.core.plugin.postoffice.cluster.jchannelfactory.MultiplexerJChannelFactory;
-import org.jboss.messaging.util.XMLUtil;
-import org.jboss.test.messaging.tools.jboss.MBeanConfigurationElement;
-import org.jboss.test.messaging.tools.jboss.ServiceDeploymentDescriptor;
-import org.jboss.test.messaging.tools.jmx.ServiceConfigHelper;
-import org.jgroups.JChannel;
-import org.w3c.dom.Element;
-
-/**
- * A JChannelFactory that reads the configuration of its synchronous/asynchronous JChannels from a
- * Messaging-style clustered persistence service configuration file (usually shipped with a
- * Messaging installation). The idea is to test with priority whatever we ship.
- *
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class ClusteredPersistenceServiceConfigFileJChannelFactory implements JChannelFactory
-{
-   // Constants ------------------------------------------------------------------------------------
-
-   public static final Logger log =
-      Logger.getLogger(ClusteredPersistenceServiceConfigFileJChannelFactory.class);
-
-   // Static ---------------------------------------------------------------------------------------
-
-   // Attributes -----------------------------------------------------------------------------------
-
-   private String configFilePath;
-
-   // we're either using a delegate MultiplexerJChannelFactory, if we find one configured in the
-   // file ...
-   private JChannelFactory multiplexorDelegate;
-
-   // ... or just plain XML configuration.
-   private Element syncConfig;
-   private Element asyncConfig;
-
-   // Constructors ---------------------------------------------------------------------------------
-
-   /**
-    * @param configFilePath - the configuration file to read JGroups stack configurations from. Must
-    *        be relative to classpath components in order to be found.
-    * @param skipMultiplex - if true, ignore multiplex option, even if a channel factory name is
-    *        found in the configuration file. Otherwise, the channel factory will take priority
-    *        if found.
-    * @param mbeanServer - the MBeanServer instance, needed in case a channel factory name is found
-    *        in the configuration file. In this situation, the channel factory is preferred.
-    *        Irrelevant if skipMultiplex is true.
-    */
-   public ClusteredPersistenceServiceConfigFileJChannelFactory(String configFilePath,
-                                                               boolean skipMultiplex,
-                                                               MBeanServer mbeanServer)
-      throws Exception
-   {
-      this.configFilePath = configFilePath;
-      init(configFilePath, skipMultiplex, mbeanServer);
-   }
-
-   // JChannelFactory ------------------------------------------------------------------------------
-
-   public JChannel createSyncChannel() throws Exception
-   {
-      if (multiplexorDelegate != null)
-      {
-         return multiplexorDelegate.createSyncChannel();
-      }
-      else
-      {
-         return new JChannel(syncConfig);
-      }
-   }
-
-   public JChannel createASyncChannel() throws Exception
-   {
-      if (multiplexorDelegate != null)
-      {
-         return multiplexorDelegate.createASyncChannel();
-      }
-      else
-      {
-         return new JChannel(asyncConfig);
-      }
-   }
-
-   // Public ---------------------------------------------------------------------------------------
-
-   public String toString()
-   {
-      return "ClusteredPersistenceServiceConfigFileJChannelFactory[" + configFilePath + "]";
-   }
-
-   // Package protected ----------------------------------------------------------------------------
-
-   // Protected ------------------------------------------------------------------------------------
-
-   // Private --------------------------------------------------------------------------------------
-
-   private void init(String configFilePath, boolean skipMultiplex, MBeanServer mbeanServer)
-      throws Exception
-   {
-      log.debug("using configuration file " + configFilePath);
-
-      MBeanConfigurationElement postOfficeConfig =
-         ServiceConfigHelper.loadServiceConfiguration(configFilePath, "PostOffice");
-
-      // first, we try to use a channel factory service, if we find one configured
-      String s = (String)postOfficeConfig.getAttributeValue("ChannelFactoryName");
-
-      if (s != null && !skipMultiplex)
-      {
-         // there's a chance we can use a multiplexer service
-         ObjectName channelFactoryName = new ObjectName(s);
-
-         String channelPartitionName =
-            (String)postOfficeConfig.getAttributeValue("ChannelPartitionName");
-
-         if (channelPartitionName == null)
-         {
-            throw new IllegalStateException("Cannot find ChannelPartitionName");
-         }
-
-         String syncChannelName = (String)postOfficeConfig.getAttributeValue("SyncChannelName");
-
-         if (syncChannelName == null)
-         {
-            throw new IllegalStateException("Cannot find SyncChannelName");
-         }
-
-         String asyncChannelName = (String)postOfficeConfig.getAttributeValue("AsyncChannelName");
-
-         if (asyncChannelName == null)
-         {
-            throw new IllegalStateException("Cannot find AsyncChannelName");
-         }
-
-         try
-         {
-            if(mbeanServer.getMBeanInfo(channelFactoryName) != null)
-            {
-               multiplexorDelegate =
-                  new MultiplexerJChannelFactory(mbeanServer, channelFactoryName,
-                                                 channelPartitionName, syncChannelName,
-                                                 asyncChannelName);
-
-               // initialization ends here, we've found what we were looking for
-               return;
-            }
-         }
-         catch (Exception e)
-         {
-            // that's alright, no multiplexer there, use the regular XML configuration
-            log.debug("Wasn't able to find " + s);
-         }
-      }
-
-      // the only chance now is to use the XML configurations
-
-      s = (String)postOfficeConfig.getAttributeValue("SyncChannelConfig");
-
-      if (s == null)
-      {
-         throw new IllegalStateException("Cannot find SyncChannelConfig");
-      }
-
-      syncConfig = XMLUtil.stringToElement(s);
-
-      s = (String)postOfficeConfig.getAttributeValue("AsyncChannelConfig");
-
-      if (s == null)
-      {
-         throw new IllegalStateException("Cannot find AsyncChannelConfig");
-      }
-
-      asyncConfig = XMLUtil.stringToElement(s);
-   }
-
-   // Inner classes --------------------------------------------------------------------------------
-
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/ClusteredPostOfficeConfigurationTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/ClusteredPostOfficeConfigurationTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/ClusteredPostOfficeConfigurationTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,146 +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.postoffice.cluster;
-
-import java.lang.reflect.Field;
-import java.net.InetAddress;
-import java.util.Properties;
-import java.util.Vector;
-
-import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
-import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
-import org.jboss.test.messaging.core.plugin.base.PostOfficeTestBase;
-import org.jgroups.JChannel;
-import org.jgroups.protocols.UDP;
-import org.jgroups.stack.Protocol;
-
-/**
- * This test assumes that bind_addr is not set in the clustered-*-persistence.xml
- * configuration file!
- * TODO this test actually tests JGroups rather than Messaging
- *
- * @author <a href="mailto:sergey.koshcheyev at jboss.com">Sergey Koshcheyev</a>
- * @version <tt>$Revision$</tt>
- * 
- * $Id$
- */
-public class ClusteredPostOfficeConfigurationTest extends PostOfficeTestBase
-{
-   public ClusteredPostOfficeConfigurationTest(String name)
-   {
-      super(name);
-   }
-   
-   private Properties savedProperties;
-   
-   protected void setUp() throws Exception
-   {
-      super.setUp();
-      
-      savedProperties = (Properties) System.getProperties().clone();
-      
-      Properties systemProperties = System.getProperties();
-      
-      // Remove JGroups properties if there are any
-      systemProperties.remove(org.jgroups.Global.BIND_ADDR_OLD);
-      systemProperties.remove(org.jgroups.Global.IGNORE_BIND_ADDRESS_PROPERTY_OLD);
-
-      systemProperties.remove(org.jgroups.Global.BIND_ADDR);
-      systemProperties.remove(org.jgroups.Global.IGNORE_BIND_ADDRESS_PROPERTY);
-   }
-   
-   protected void tearDown() throws Exception
-   {
-      System.setProperties(savedProperties);
-      super.tearDown();
-   }
-   
-   protected ClusteredPostOffice createClusteredPostOfficeSimple() throws Exception {
-      return createClusteredPostOffice(1, "testgroup", sc, ms, pm, tr);
-   }
-   
-   // TODO these two methods are of course very ugly
-   private static JChannel getPostOfficeSyncChannel(ClusteredPostOffice postOffice) throws Exception {
-      Field field = DefaultClusteredPostOffice.class.getDeclaredField("syncChannel");
-      field.setAccessible(true);
-      return (JChannel) field.get(postOffice);
-   }
-   
-   private static JChannel getPostOfficeAsyncChannel(ClusteredPostOffice postOffice) throws Exception {
-      Field field = DefaultClusteredPostOffice.class.getDeclaredField("asyncChannel");
-      field.setAccessible(true);
-      return (JChannel) field.get(postOffice);
-   }
-   
-   private static String getUDPBindAddress(JChannel channel) {
-      Vector protocols = channel.getProtocolStack().getProtocols();
-      for (int i = 0; i < protocols.size(); i++) {
-         Protocol protocol = (Protocol) protocols.get(i);
-         if (protocol instanceof UDP) {
-            return ((UDP) protocol).getBindAddress();
-         }
-      }
-      
-      return null;
-   }
-
-   private void assertChannelsBoundTo(InetAddress bindAddress) throws Exception {
-      String addressAsString = bindAddress.toString();
-      ClusteredPostOffice postOffice = createClusteredPostOfficeSimple();
-      
-      try {
-         JChannel syncChannel = getPostOfficeSyncChannel(postOffice);
-         assertEquals(addressAsString, getUDPBindAddress(syncChannel));
-         
-         JChannel asyncChannel = getPostOfficeAsyncChannel(postOffice);
-         assertEquals(addressAsString, getUDPBindAddress(asyncChannel));
-      } finally {
-         postOffice.stop();
-      }
-   }
-
-   public void testNoProperties() throws Exception {
-      InetAddress address = org.jgroups.util.Util.getFirstNonLoopbackAddress();
-      if (address == null) {
-         fail("No address available for JGroups to bind to");
-      }
-      assertChannelsBoundTo(address);
-   }
-   
-   public void testBindAddressPropertySet() throws Exception {
-      String address = "127.0.0.1";
-      System.setProperty(org.jgroups.Global.BIND_ADDR, address);
-      assertChannelsBoundTo(InetAddress.getByName(address));
-   }
-   
-   public void testIgnoreBindAddressPropertySet() throws Exception {
-      InetAddress defaultAddress = org.jgroups.util.Util.getFirstNonLoopbackAddress();
-      if (defaultAddress == null) {
-         fail("No address available for JGroups to bind to");
-      }
-      
-      String address = "127.0.0.1";
-      System.setProperty(org.jgroups.Global.BIND_ADDR, address);
-      System.setProperty(org.jgroups.Global.IGNORE_BIND_ADDRESS_PROPERTY, "true");
-      assertChannelsBoundTo(defaultAddress);
-   }
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,2407 +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.postoffice.cluster;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import org.jboss.messaging.core.local.PagingFilteredQueue;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
-import org.jboss.messaging.core.plugin.postoffice.Binding;
-import org.jboss.messaging.core.plugin.postoffice.cluster.LocalClusteredQueue;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.test.messaging.core.SimpleCondition;
-import org.jboss.test.messaging.core.SimpleFilter;
-import org.jboss.test.messaging.core.SimpleReceiver;
-import org.jboss.test.messaging.core.plugin.postoffice.DefaultPostOfficeTest;
-import org.jboss.test.messaging.util.CoreMessageFactory;
-
-/**
- * 
- * A DefaultClusteredPostOfficeTest
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public class DefaultClusteredPostOfficeTest extends DefaultPostOfficeTest
-{
-   // Constants ------------------------------------------------------------------------------------
-
-   // Static ---------------------------------------------------------------------------------------
-   
-   // Attributes -----------------------------------------------------------------------------------
-    
-   // Constructors ---------------------------------------------------------------------------------
-
-   public DefaultClusteredPostOfficeTest(String name)
-   {
-      super(name);
-   }
-
-   // Public ---------------------------------------------------------------------------------------
-
-   public final void testSimpleJoinLeave() throws Throwable
-   {
-      ClusteredPostOffice office1 = null;
-      ClusteredPostOffice office2 = null;
-      ClusteredPostOffice office3 = null;
-      
-      try
-      {         
-         log.trace("Starting office 1");
-         office1 = createClusteredPostOffice(1, "testgroup", sc, ms, pm, tr);
-
-         log.trace("starting office 2");
-         office2 = createClusteredPostOffice(2, "testgroup", sc, ms, pm, tr);
-                  
-         office3 = createClusteredPostOffice(3, "testgroup", sc, ms, pm, tr);
-         
-         Thread.sleep(2000);
-         
-         office1.stop();
-         office1 = null;
-         
-         office2.stop();
-         office2 = null;
-         
-         office3.stop();
-         office3 = null;
-      }
-      finally
-      {
-         if (office1 != null)
-         {
-            office1.stop();
-         }
-         
-         if (office2 != null)
-         {
-            office2.stop();
-         }
-         
-         if (office3 != null)
-         {
-            office3.stop();
-         }
-         
-//         if (checkNoBindingData())
-//         {
-//            fail("data still in database");
-//         }
-      }
-         
-   }
-   
-   public final void testClusteredBindUnbind() throws Throwable
-   {
-      ClusteredPostOffice office1 = null;
-      ClusteredPostOffice office2 = null;
-      ClusteredPostOffice office3 = null;
-      
-      try
-      {         
-         // Start one office
-         
-         office1 = createClusteredPostOffice(1, "testgroup", sc, ms, pm, tr);
-         
-         log.info("Created office1");
-         
-         // Add a couple of bindings
-         
-         LocalClusteredQueue queue1 =
-            new LocalClusteredQueue(office1, 1, "sub1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-
-         Binding binding1 =
-            office1.bindClusteredQueue(new SimpleCondition("topic1"), queue1);
-         
-         log.info("Added binding1");
-         
-         LocalClusteredQueue queue2 =
-            new LocalClusteredQueue(office1, 1, "sub2", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-
-         Binding binding2 =
-            office1.bindClusteredQueue(new SimpleCondition("topic1"), queue2);
-         
-         log.info("Added binding2");
-         
-         // Start another office - make sure it picks up the bindings from the first node
-         
-         office2 = createClusteredPostOffice(2, "testgroup", sc, ms, pm, tr);
-         
-         log.info("Created office 2");
-         
-         Collection bindings = office2.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(2, bindings.size());
-         
-         Iterator iter = bindings.iterator();
-         assertEquivalent(binding1, (Binding)iter.next());
-         assertEquivalent(binding2, (Binding)iter.next());         
-         
-         // Add another binding on node 2
-         
-         LocalClusteredQueue queue3 =
-            new LocalClusteredQueue(office2, 2, "sub3", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-
-         Binding binding3 =
-            office2.bindClusteredQueue(new SimpleCondition("topic1"), queue3);
-  
-         // Make sure both nodes pick it up
-         
-         bindings = office1.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(3, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding1, (Binding)iter.next());
-         assertEquivalent(binding2, (Binding)iter.next());
-         assertEquivalent(binding3, (Binding)iter.next());
-
-         bindings = office2.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(3, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding1, (Binding)iter.next());
-         assertEquivalent(binding2, (Binding)iter.next());
-         assertEquivalent(binding3, (Binding)iter.next());
-
-         // Add another binding on node 1
-         
-         LocalClusteredQueue queue4 =
-            new LocalClusteredQueue(office2, 2, "sub4", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-
-         Binding binding4 =
-            office2.bindClusteredQueue(new SimpleCondition("topic1"), queue4);
-         
-         // Make sure both nodes pick it up
-         
-         bindings = office1.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(4, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding1, (Binding)iter.next());
-         assertEquivalent(binding2, (Binding)iter.next());
-         assertEquivalent(binding3, (Binding)iter.next());
-         assertEquivalent(binding4, (Binding)iter.next());
-         
-         bindings = office2.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(4, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding1, (Binding)iter.next());
-         assertEquivalent(binding2, (Binding)iter.next());
-         assertEquivalent(binding3, (Binding)iter.next());
-         assertEquivalent(binding4, (Binding)iter.next());
-         
-         // Unbind binding 1 and binding 2
-         office1.unbindClusteredQueue("sub1");
-         office1.unbindClusteredQueue("sub2");
-         
-         // Make sure bindings are not longer available on either node
-         
-         bindings = office1.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(2, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding3, (Binding)iter.next());
-         assertEquivalent(binding4, (Binding)iter.next());
-   
-         bindings = office2.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(2, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding3, (Binding)iter.next());
-         assertEquivalent(binding4, (Binding)iter.next());
-
-         // Add a third office
-                  
-         office3 = createClusteredPostOffice(3, "testgroup", sc, ms, pm, tr);
-         
-         // Maks sure it picks up the bindings
-         
-         bindings = office3.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(2, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding3, (Binding)iter.next());
-         assertEquivalent(binding4, (Binding)iter.next());
-         
-         // Add another binding on node 3
-                  
-         LocalClusteredQueue queue5 =
-            new LocalClusteredQueue(office3, 3, "sub5", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         
-         Binding binding5 =
-            office3.bindClusteredQueue(new SimpleCondition("topic1"), queue5);
-         
-         // Make sure all nodes pick it up
-         
-         bindings = office1.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(3, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding3, (Binding)iter.next());
-         assertEquivalent(binding4, (Binding)iter.next());
-         assertEquivalent(binding5, (Binding)iter.next());
-         
-         bindings = office2.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(3, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding3, (Binding)iter.next());
-         assertEquivalent(binding4, (Binding)iter.next());
-         assertEquivalent(binding5, (Binding)iter.next());
-         
-         bindings = office3.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(3, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding3, (Binding)iter.next());
-         assertEquivalent(binding4, (Binding)iter.next());
-         assertEquivalent(binding5, (Binding)iter.next());
-         
-         // Add a durable and a non durable binding on node 1
-         
-         LocalClusteredQueue queue6 =
-            new LocalClusteredQueue(office1, 1, "sub6", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-         
-         Binding binding6 =
-            office1.bindClusteredQueue(new SimpleCondition("topic1"), queue6);
-         
-         LocalClusteredQueue queue7 =
-            new LocalClusteredQueue(office1, 1, "sub7", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         
-         Binding binding7 =
-            office1.bindClusteredQueue(new SimpleCondition("topic1"), queue7);
-         
-         // Make sure all nodes pick them up
-         
-         bindings = office1.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(5, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding3, (Binding)iter.next());
-         assertEquivalent(binding4, (Binding)iter.next());
-         assertEquivalent(binding5, (Binding)iter.next());
-         assertEquivalent(binding6, (Binding)iter.next());
-         assertEquivalent(binding7, (Binding)iter.next());
-         
-         bindings = office2.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(5, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding3, (Binding)iter.next());
-         assertEquivalent(binding4, (Binding)iter.next());
-         assertEquivalent(binding5, (Binding)iter.next());
-         assertEquivalent(binding6, (Binding)iter.next());
-         assertEquivalent(binding7, (Binding)iter.next());
-         
-         bindings = office3.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(5, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding3, (Binding)iter.next());
-         assertEquivalent(binding4, (Binding)iter.next());
-         assertEquivalent(binding5, (Binding)iter.next());
-         assertEquivalent(binding6, (Binding)iter.next());
-         assertEquivalent(binding7, (Binding)iter.next());
-               
-         // Stop office 1
-         office1.stop();
-  
-         // Need to sleep since it may take some time for the view changed request to reach the
-         // members which causes the bindings to be removed.
-         
-         Thread.sleep(1000);
-         
-         // All it's non durable bindings should be removed from the other nodes.
-         // Durable bindings should remain.
-         
-         bindings = office2.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(4, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding3, (Binding)iter.next());
-         assertEquivalent(binding4, (Binding)iter.next());
-         assertEquivalent(binding5, (Binding)iter.next());
-         assertEquivalent(binding6, (Binding)iter.next());
-         
-         bindings = office3.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(4, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding3, (Binding)iter.next());
-         assertEquivalent(binding4, (Binding)iter.next());
-         assertEquivalent(binding5, (Binding)iter.next());
-         assertEquivalent(binding6, (Binding)iter.next());
-         
-         // Stop office 2
-         office2.stop();
-         
-         bindings = office3.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(2, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding5, (Binding)iter.next());
-         assertEquivalent(binding6, (Binding)iter.next());
-         
-         // Restart office 1 and office 2
-         office1 = createClusteredPostOffice(1, "testgroup", sc, ms, pm, tr);
-         
-         office2 = createClusteredPostOffice(2, "testgroup", sc, ms, pm, tr);
-         
-         bindings = office1.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(2, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding5, (Binding)iter.next());
-         assertEquivalent(binding6, (Binding)iter.next());
-         
-         bindings = office2.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(2, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding5, (Binding)iter.next());
-         assertEquivalent(binding6, (Binding)iter.next());
-         
-         bindings = office3.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(2, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding5, (Binding)iter.next());
-         assertEquivalent(binding6, (Binding)iter.next());
-         
-         // Stop all offices
-         
-         office1.stop();
-         office2.stop();
-         office3.stop();
-         
-         // Start them all
-         office1 = createClusteredPostOffice(1, "testgroup", sc, ms, pm, tr);
-         office2 = createClusteredPostOffice(2, "testgroup", sc, ms, pm, tr);
-         office3 = createClusteredPostOffice(3, "testgroup", sc, ms, pm, tr);
-         
-         // Only the durable queue should survive
-         
-         bindings = office1.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(1, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding6, (Binding)iter.next());
-         
-         bindings = office2.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(1, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding6, (Binding)iter.next());
-         
-         bindings = office3.listAllBindingsForCondition(new SimpleCondition("topic1"));
-         assertNotNull(bindings);
-         assertEquals(1, bindings.size());
-         
-         iter = bindings.iterator();
-         assertEquivalent(binding6, (Binding)iter.next());
-                  
-      }
-      finally
-      {
-         if (office1 != null)
-         {
-            try
-            {
-               office1.unbindClusteredQueue("sub6");
-            }
-            catch (Exception ignore)
-            {
-               
-            }
-            office1.stop();
-         }
-         
-         if (office2 != null)
-         {
-            office2.stop();
-         }
-         
-         if (office3 != null)
-         {
-            office3.stop();
-         }
-         
-         if (checkNoBindingData())
-         {
-            fail("data still in database");
-         }
-      }
-   }
-   
-   public final void testClusteredRoutePersistent() throws Throwable
-   {
-      clusteredRoute(true);
-   }
-   
-   public final void testClusteredRouteNonPersistent() throws Throwable
-   {
-      clusteredRoute(false);
-   }
-   
-   public final void testClusteredTransactionalRoutePersistent() throws Throwable
-   {
-      clusteredTransactionalRoute(true);
-   }
-   
-   public final void testClusteredTransactionalRouteNonPersistent() throws Throwable
-   {
-      clusteredTransactionalRoute(false);
-   }
-   
-   public void testClusteredNonPersistentRouteWithFilterNonRecoverable() throws Throwable
-   {
-      this.clusteredRouteWithFilter(false, false);
-   }
-   
-   public void testClusteredPersistentRouteWithFilterNonRecoverable() throws Throwable
-   {
-      this.clusteredRouteWithFilter(true, false);
-   }
-   
-   public void testClusteredNonPersistentRouteWithFilterRecoverable() throws Throwable
-   {
-      this.clusteredRouteWithFilter(false, true);
-   }
-   
-   public void testClusteredPersistentRouteWithFilterRecoverable() throws Throwable
-   {
-      this.clusteredRouteWithFilter(true, true);
-   }
-      
-   public void testRouteSharedPointToPointQueuePersistentNonRecoverable() throws Throwable
-   {
-      this.routeSharedQueue(true, false);
-   }
-   
-   public void testRouteSharedPointToPointQueueNonPersistentNonRecoverable() throws Throwable
-   {
-      this.routeSharedQueue(false, false);
-   }
-   
-   public void testRouteSharedPointToPointQueuePersistentRecoverable() throws Throwable
-   {
-      this.routeSharedQueue(true, true);
-   }
-   
-   public void testRouteSharedPointToPointQueueNonPersistentRecoverable() throws Throwable
-   {
-      this.routeSharedQueue(false, true);
-   }
-   
-   public void testRouteComplexTopicPersistent() throws Throwable
-   {
-      this.routeComplexTopic(true);
-   }
-   
-   public void testRouteComplexTopicNonPersistent() throws Throwable
-   {
-      this.routeComplexTopic(false);
-   }
-         
-   public void testRouteLocalQueuesPersistentNonRecoverable() throws Throwable
-   {
-      this.routeLocalQueues(true, false);
-   }
-   
-   public void testRouteLocalQueuesNonPersistentNonRecoverable() throws Throwable
-   {
-      this.routeLocalQueues(false, false);
-   }
-   
-   public void testRouteLocalQueuesPersistentRecoverable() throws Throwable
-   {
-      this.routeLocalQueues(true, true);
-   }
-   
-   public void testRouteLocalQueuesNonPersistentRecoverable() throws Throwable
-   {
-      this.routeLocalQueues(false, true);
-   }
-   
-   
-   /*
-    * We should allow the clustered bind of queues with the same queue name on different nodes of the
-    * cluster
-    */
-   public void testClusteredNameUniqueness() throws Throwable
-   {
-      ClusteredPostOffice office1 = null;
-      
-      ClusteredPostOffice office2 = null;
-          
-      try
-      {   
-         office1 = createClusteredPostOffice(1, "testgroup", sc, ms, pm, tr);
-         
-         office2 = createClusteredPostOffice(2, "testgroup", sc, ms, pm, tr);
-         
-         LocalClusteredQueue queue1 =
-            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         
-         office1.bindClusteredQueue(new SimpleCondition("queue1"), queue1);
-
-         LocalClusteredQueue queue2 =
-            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-
-         office2.bindClusteredQueue(new SimpleCondition("queue1"), queue2);
-
-         LocalClusteredQueue queue3 =
-            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         
-         try
-         {
-            office1.bindClusteredQueue(new SimpleCondition("queue1"), queue3);
-            fail();
-         }
-         catch (Exception e)
-         {
-            //Ok
-         }
-
-         LocalClusteredQueue queue4 =
-            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         
-         try
-         {
-            office2.bindClusteredQueue(new SimpleCondition("queue1"), queue4);
-            fail();
-         }
-         catch (Exception e)
-         {
-            //Ok
-         }
-         
-         office2.unbindClusteredQueue("queue1");
-
-         office1.unbindClusteredQueue("queue1");
-
-         LocalClusteredQueue queue5 =
-            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         
-         office1.bindClusteredQueue(new SimpleCondition("queue1"), queue5);
-         
-         PagingFilteredQueue queue6 =
-            new PagingFilteredQueue("queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null);
-         try
-         {
-            office1.bindQueue(new SimpleCondition("queue1"), queue6);
-            fail();
-         }
-         catch (Exception e)
-         {
-            //ok
-         }
-          
-         office1.unbindClusteredQueue("queue1");
-         
-         // It should be possible to bind queues locally into a clustered post office
-         LocalClusteredQueue queue7 =
-            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-
-         office1.bindQueue(new SimpleCondition("queue1"), queue7);
-         
-         LocalClusteredQueue queue8 =
-            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-
-         office2.bindQueue(new SimpleCondition("queue1"), queue8);
-         
-         LocalClusteredQueue queue9 =
-            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-
-         try
-         {
-            office1.bindQueue(new SimpleCondition("queue1"), queue9);
-            fail();
-         }
-         catch (Exception e)
-         {
-            //Ok
-         }
-
-      }
-      finally
-      {
-         if (office1 != null)
-         {            
-            office1.stop();
-         }
-         
-         if (office2 != null)
-         {
-            office2.stop();
-         }
-      }
-   }
- 
-   // Package protected ----------------------------------------------------------------------------
-
-   // Protected ------------------------------------------------------------------------------------
-   
-   protected void clusteredRouteWithFilter(boolean persistentMessage, boolean recoverable)
-      throws Throwable
-   {
-      ClusteredPostOffice office1 = null;
-      
-      ClusteredPostOffice office2 = null;
-          
-      try
-      {   
-         office1 = createClusteredPostOffice(1, "testgroup", sc, ms, pm, tr);
-         office2 = createClusteredPostOffice(2, "testgroup", sc, ms, pm, tr);
-         
-         SimpleFilter filter1 = new SimpleFilter(2);
-         SimpleFilter filter2 = new SimpleFilter(3);
-      
-         LocalClusteredQueue queue1 =
-            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, recoverable, -1, filter1, tr);
-
-         office1.bindClusteredQueue(new SimpleCondition("topic1"), queue1);
-         
-         LocalClusteredQueue queue2 =
-            new LocalClusteredQueue(office2, 2, "queue2", channelIDManager.getID(), ms, pm,
-                                    true, recoverable, -1, filter2, tr);
-
-         office2.bindClusteredQueue(new SimpleCondition("topic1"), queue2);
-         
-         LocalClusteredQueue queue3 =
-            new LocalClusteredQueue(office2, 2, "queue3", channelIDManager.getID(), ms, pm, true,
-                                    recoverable, -1, null, tr);
-
-         office2.bindClusteredQueue(new SimpleCondition("topic1"), queue3);
-         
-         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-
-         queue1.add(receiver1);
-
-         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-
-         queue2.add(receiver2);
-
-         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-
-         queue3.add(receiver3);
-         
-         Message msg1 = CoreMessageFactory.createCoreMessage(1);      
-         MessageReference ref1 = ms.reference(msg1);  
-         boolean routed = office1.route(ref1, new SimpleCondition("topic1"), null);   
-         assertTrue(routed);
-         
-         
-         Message msg2 = CoreMessageFactory.createCoreMessage(2);      
-         MessageReference ref2 = ms.reference(msg2);         
-         routed = office1.route(ref2, new SimpleCondition("topic1"), null);      
-         assertTrue(routed);
-         
-         Message msg3 = CoreMessageFactory.createCoreMessage(3);      
-         MessageReference ref3 = ms.reference(msg3);         
-         routed = office1.route(ref3, new SimpleCondition("topic1"), null);      
-         assertTrue(routed);
-         
-         Thread.sleep(2000);
-         
-         List msgs = receiver1.getMessages();
-         assertNotNull(msgs);
-         assertEquals(1, msgs.size());
-         Message msgRec = (Message)msgs.get(0);
-         assertTrue(msg2 == msgRec);
-         receiver1.acknowledge(msgRec, null);
-         msgs = queue1.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());  
-         
-         msgs = receiver2.getMessages();
-         assertNotNull(msgs);
-         assertEquals(1, msgs.size());
-         msgRec = (Message)msgs.get(0);
-         assertTrue(msg3 == msgRec);
-         receiver2.acknowledge(msgRec, null);
-         msgs = queue2.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());  
-         
-         msgs = receiver3.getMessages();
-         assertNotNull(msgs);
-         assertEquals(3, msgs.size());
-         Message msgRec1 = (Message)msgs.get(0);
-         assertTrue(msg1 == msgRec1);
-         Message msgRec2 = (Message)msgs.get(1);
-         assertTrue(msg2 == msgRec2);
-         Message msgRec3 = (Message)msgs.get(2);
-         assertTrue(msg3 == msgRec3);
-          
-         receiver3.acknowledge(msgRec1, null);
-         receiver3.acknowledge(msgRec2, null);
-         receiver3.acknowledge(msgRec3, null);
-         msgs = queue3.browse();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty()); 
-                  
-         if (checkNoMessageData())
-         {
-            fail("Message data still in database");
-         }
-      }
-      finally
-      {
-         if (office1 != null)
-         {
-            office1.stop();
-         }
-         
-         if (office2 != null)
-         {
-            office2.stop();
-         }
-         
-      }
-   }
-   
-   protected void clusteredRoute(boolean persistentMessage) throws Throwable
-   {
-      ClusteredPostOffice office1 = null;
-      
-      ClusteredPostOffice office2 = null;
-          
-      try
-      {   
-         office1 = createClusteredPostOffice(1, "testgroup", sc, ms, pm, tr);
-         office2 = createClusteredPostOffice(2, "testgroup", sc, ms, pm, tr);
-      
-         //Two topics with a mixture of durable and non durable subscriptions
-         
-         LocalClusteredQueue[] queues = new LocalClusteredQueue[16];
-         Binding[] bindings = new Binding[16];
-         
-         queues[0] = new LocalClusteredQueue(office1, 1, "sub1", channelIDManager.getID(), ms, pm, true, false, -1, null, tr);
-         bindings[0] = office1.bindClusteredQueue(new SimpleCondition("topic1"), queues[0]);
-         
-         queues[1] = new LocalClusteredQueue(office1, 1, "sub2", channelIDManager.getID(), ms, pm, true, false, -1, null, tr);
-         bindings[1] = office1.bindClusteredQueue(new SimpleCondition("topic1"), queues[1]);
-         
-         queues[2] = new LocalClusteredQueue(office2, 2, "sub3", channelIDManager.getID(), ms, pm, true, false, -1, null, tr);
-         bindings[2] = office2.bindClusteredQueue(new SimpleCondition("topic1"), queues[2]);
-         
-         queues[3] = new LocalClusteredQueue(office2, 2, "sub4", channelIDManager.getID(), ms, pm, true, false, -1, null, tr);
-         bindings[3] = office2.bindClusteredQueue(new SimpleCondition("topic1"), queues[3]);
-         
-         queues[4] = new LocalClusteredQueue(office2, 2, "sub5", channelIDManager.getID(), ms, pm, true, true, -1, null, tr);
-         bindings[4] = office2.bindClusteredQueue(new SimpleCondition("topic1"), queues[4]);
-         
-         queues[5] = new LocalClusteredQueue(office1, 1, "sub6", channelIDManager.getID(), ms, pm, true, false, -1, null, tr);
-         bindings[5] = office1.bindClusteredQueue(new SimpleCondition("topic1"), queues[5]);
-         
-         queues[6] = new LocalClusteredQueue(office1, 1, "sub7", channelIDManager.getID(), ms, pm, true, true, -1, null, tr);
-         bindings[6] = office1.bindClusteredQueue(new SimpleCondition("topic1"), queues[6]);
-         
-         queues[7] = new LocalClusteredQueue(office1, 1, "sub8", channelIDManager.getID(), ms, pm, true, true, -1, null, tr);
-         bindings[7] = office1.bindClusteredQueue(new SimpleCondition("topic1"), queues[7]);
-         
-         queues[8] = new LocalClusteredQueue(office1, 1, "sub9", channelIDManager.getID(), ms, pm, true, false, -1, null, tr);
-         bindings[8] = office1.bindClusteredQueue(new SimpleCondition("topic2"), queues[8]);
-         
-         queues[9] = new LocalClusteredQueue(office1, 1, "sub10", channelIDManager.getID(), ms, pm, true, false, -1, null, tr);
-         bindings[9] = office1.bindClusteredQueue(new SimpleCondition("topic2"), queues[9]);
-         
-         queues[10] = new LocalClusteredQueue(office2, 2, "sub11", channelIDManager.getID(), ms, pm, true, false, -1, null, tr);
-         bindings[10] = office2.bindClusteredQueue(new SimpleCondition("topic2"), queues[10]);
-         
-         queues[11] = new LocalClusteredQueue(office2, 2, "sub12", channelIDManager.getID(), ms, pm, true, false, -1, null, tr);
-         bindings[11] = office2.bindClusteredQueue(new SimpleCondition("topic2"), queues[11]);
-         
-         queues[12] = new LocalClusteredQueue(office2, 2, "sub13", channelIDManager.getID(), ms, pm, true, true, -1, null, tr);
-         bindings[12] = office2.bindClusteredQueue(new SimpleCondition("topic2"), queues[12]);
-         
-         queues[13] = new LocalClusteredQueue(office1, 1, "sub14", channelIDManager.getID(), ms, pm, true, false, -1, null, tr);
-         bindings[13] = office1.bindClusteredQueue(new SimpleCondition("topic2"), queues[13]);
-         
-         queues[14] = new LocalClusteredQueue(office1, 1, "sub15", channelIDManager.getID(), ms, pm, true, true, -1, null, tr);
-         bindings[14] = office1.bindClusteredQueue(new SimpleCondition("topic2"), queues[14]);
-         
-         queues[15] = new LocalClusteredQueue(office1, 1, "sub16", channelIDManager.getID(), ms, pm, true, true, -1, null, tr);
-         bindings[15] = office1.bindClusteredQueue(new SimpleCondition("topic2"), queues[15]);
-       
-         SimpleReceiver[] receivers = new SimpleReceiver[16];
-         
-         for (int i = 0; i < 16; i++)
-         {
-            receivers[i] = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-            queues[i].add(receivers[i]);
-         }
-         
-         Message msg = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
-         MessageReference ref = ms.reference(msg);         
-
-         boolean routed = office1.route(ref, new SimpleCondition("topic1"), null);         
-         assertTrue(routed);
-         
-         //Messages are sent asych so may take some finite time to arrive
-         Thread.sleep(1000);
-         
-         for (int i = 0; i < 8; i++)
-         {         
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertEquals(1, msgs.size());
-            Message msgRec = (Message)msgs.get(0);
-            assertEquals(msg.getMessageID(), msgRec.getMessageID());
-            receivers[i].acknowledge(msgRec, null);
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty()); 
-            receivers[i].clear();
-         }
-         
-         for (int i = 8; i < 16; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-                  
-         //Now route to topic2
-         
-         msg = CoreMessageFactory.createCoreMessage(2, persistentMessage, null);;      
-         ref = ms.reference(msg);         
-
-         routed = office1.route(ref, new SimpleCondition("topic2"), null);         
-         assertTrue(routed);
-         //Messages are sent asych so may take some finite time to arrive
-         Thread.sleep(1000);
-         
-         for (int i = 0; i < 8; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         for (int i = 8; i < 16; i++)
-         {         
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertEquals(1, msgs.size());
-            Message msgRec = (Message)msgs.get(0);
-            assertEquals(msg.getMessageID(), msgRec.getMessageID());
-            receivers[i].acknowledge(msgRec, null);
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty()); 
-            receivers[i].clear();
-         }
-         
-         if (checkNoMessageData())
-         {
-            fail("Message data still in database");
-         }
-
-      }
-      finally
-      {
-         if (office1 != null)
-         {
-            try
-            {              
-               office1.unbindClusteredQueue("sub7");
-               office1.unbindClusteredQueue("sub8");               
-               office1.unbindClusteredQueue("sub15");
-               office1.unbindClusteredQueue("sub16");
-            }
-            catch (Exception ignore)
-            {
-               ignore.printStackTrace();
-            }
-            
-            office1.stop();
-         }
-         
-         if (office2 != null)
-         {
-            try
-            {
-               office2.unbindClusteredQueue("sub5");
-               office2.unbindClusteredQueue("sub13");
-            }
-            catch (Exception ignore)
-            {     
-               ignore.printStackTrace();
-            }
-            office2.stop();
-         }
-        
-      }
-   }
-   
-   protected void routeSharedQueue(boolean persistentMessage, boolean recoverable) throws Throwable
-   {
-      ClusteredPostOffice office1 = null;
-      
-      ClusteredPostOffice office2 = null;
-      
-      ClusteredPostOffice office3 = null;
-      
-      ClusteredPostOffice office4 = null;
-      
-      ClusteredPostOffice office5 = null;
-      
-      ClusteredPostOffice office6 = null;
-        
-      try
-      {   
-         office1 = createClusteredPostOffice(1, "testgroup", sc, ms, pm, tr);
-         office2 = createClusteredPostOffice(2, "testgroup", sc, ms, pm, tr);
-         office3 = createClusteredPostOffice(3, "testgroup", sc, ms, pm, tr);
-         office4 = createClusteredPostOffice(4, "testgroup", sc, ms, pm, tr);
-         office5 = createClusteredPostOffice(5, "testgroup", sc, ms, pm, tr);
-         office6 = createClusteredPostOffice(6, "testgroup", sc, ms, pm, tr);
-    
-         // We deploy the queue on nodes 1, 2, 3, 4 and 5
-         // We don't deploy on node 6
-         
-         LocalClusteredQueue queue1 =
-            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm, true,
-                                    recoverable, -1, null, tr);
-
-         office1.bindClusteredQueue(new SimpleCondition("queue1"), queue1);
-
-         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue1.add(receiver1);
-         
-         LocalClusteredQueue queue2 =
-            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm, true,
-                                    recoverable, -1, null, tr);
-
-         office2.bindClusteredQueue(new SimpleCondition("queue1"), queue2);
-
-         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue2.add(receiver2);
-         
-         LocalClusteredQueue queue3 =
-            new LocalClusteredQueue(office3, 3, "queue1", channelIDManager.getID(), ms, pm, true,
-                                    recoverable, -1, null, tr);
-
-         office3.bindClusteredQueue(new SimpleCondition("queue1"), queue3);
-
-         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue3.add(receiver3);
-         
-         LocalClusteredQueue queue4 =
-            new LocalClusteredQueue(office4, 4, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, recoverable, -1, null, tr);
-
-         office4.bindClusteredQueue(new SimpleCondition("queue1"), queue4);
-
-         SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue4.add(receiver4);
-         
-         LocalClusteredQueue queue5 =
-            new LocalClusteredQueue(office5, 5, "queue1", channelIDManager.getID(), ms, pm, true,
-                                    recoverable, -1, null, tr);
-
-         office5.bindClusteredQueue(new SimpleCondition("queue1"), queue5);
-         SimpleReceiver receiver5 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue5.add(receiver5);
-        
-         // We are using a AlwaysLocalRoutingPolicy so only the local queue should ever get the
-         // message if the filter matches
-                          
-         Message msg = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
-         MessageReference ref = ms.reference(msg);         
-         boolean routed = office1.route(ref, new SimpleCondition("queue1"), null);         
-         assertTrue(routed);
-         checkContainsAndAcknowledge(msg, receiver1, queue1);
-         this.checkEmpty(receiver2);
-         this.checkEmpty(receiver3);
-         this.checkEmpty(receiver4);
-         this.checkEmpty(receiver5);
-         
-         msg = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
-         ref = ms.reference(msg);         
-         routed = office2.route(ref, new SimpleCondition("queue1"), null);         
-         assertTrue(routed);
-         this.checkEmpty(receiver1);
-         checkContainsAndAcknowledge(msg, receiver2, queue2);
-         this.checkEmpty(receiver3);
-         this.checkEmpty(receiver4);
-         this.checkEmpty(receiver5);
-         
-         msg = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
-         ref = ms.reference(msg);         
-         routed = office3.route(ref, new SimpleCondition("queue1"), null);         
-         assertTrue(routed);
-         this.checkEmpty(receiver1);
-         this.checkEmpty(receiver2);
-         checkContainsAndAcknowledge(msg, receiver3, queue3);
-         this.checkEmpty(receiver4);
-         this.checkEmpty(receiver5);
-         
-         msg = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
-         ref = ms.reference(msg);         
-         routed = office4.route(ref, new SimpleCondition("queue1"), null);         
-         assertTrue(routed);
-         this.checkEmpty(receiver1);
-         this.checkEmpty(receiver2);
-         this.checkEmpty(receiver3);
-         checkContainsAndAcknowledge(msg, receiver4, queue3);
-         this.checkEmpty(receiver5);
-         
-         msg = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
-         ref = ms.reference(msg);         
-         routed = office5.route(ref, new SimpleCondition("queue1"), null);         
-         assertTrue(routed);
-         this.checkEmpty(receiver1);
-         this.checkEmpty(receiver2);         
-         this.checkEmpty(receiver3);
-         this.checkEmpty(receiver4);
-         checkContainsAndAcknowledge(msg, receiver5, queue5);
-         
-         msg = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
-         ref = ms.reference(msg);         
-         routed = office6.route(ref, new SimpleCondition("queue1"), null);         
-         assertTrue(routed);
-         
-         //The actual queue that receives the mesage is determined by the routing policy
-         //The default uses round robin for the nodes (this is tested more thoroughly in
-         //its own test)
-         
-         Thread.sleep(1000);
-         
-         checkContainsAndAcknowledge(msg, receiver1, queue1);
-         this.checkEmpty(receiver1);
-         this.checkEmpty(receiver2);         
-         this.checkEmpty(receiver3);
-         this.checkEmpty(receiver4);
-         this.checkEmpty(receiver5);
-                 
-      }
-      finally
-      {
-         if (office1 != null)
-         {            
-            office1.stop();
-         }
-         
-         if (office2 != null)
-         {
-            office2.stop();
-         }
-         
-         if (office3 != null)
-         {            
-            office3.stop();
-         }
-         
-         if (office4 != null)
-         {
-            office4.stop();
-         }
-         
-         if (office5 != null)
-         {            
-            office5.stop();
-         }
-         
-         if (office6 != null)
-         {            
-            office6.stop();
-         }
-         
-         if (checkNoMessageData())
-         {
-            fail("Message data still in database");
-         }
-      }
-   }
-   
-
-   /**
-    * Clustered post offices should be able to have local queues bound to them too.
-    */
-   protected void routeLocalQueues(boolean persistentMessage, boolean recoverable) throws Throwable
-   {
-      ClusteredPostOffice office1 = null;
-      ClusteredPostOffice office2 = null;
-      ClusteredPostOffice office3 = null;
-                    
-      try
-      {   
-         office1 = createClusteredPostOffice(1, "testgroup", sc, ms, pm, tr);
-         office2 = createClusteredPostOffice(2, "testgroup", sc, ms, pm, tr);
-         office3 = createClusteredPostOffice(3, "testgroup", sc, ms, pm, tr);
-
-         LocalClusteredQueue sub1 =
-            new LocalClusteredQueue(office1, 1, "sub1", channelIDManager.getID(), ms, pm, true,
-                                    recoverable, -1, null, tr);
-
-         office1.bindQueue(new SimpleCondition("topic"), sub1);
-
-         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         sub1.add(receiver1);
-         
-         LocalClusteredQueue sub2 =
-            new LocalClusteredQueue(office2, 2, "sub2", channelIDManager.getID(), ms, pm, true,
-                                    recoverable, -1, null, tr);
-
-         office2.bindQueue(new SimpleCondition("topic"), sub2);
-         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         sub2.add(receiver2);
-         
-         LocalClusteredQueue sub3 =
-            new LocalClusteredQueue(office3, 3, "sub3", channelIDManager.getID(), ms, pm, true,
-                                    recoverable, -1, null, tr);
-
-         office3.bindQueue(new SimpleCondition("topic"), sub3);
-         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         sub3.add(receiver3);
-         
-         //Only the local sub should get it since we have bound locally
-         
-         Message msg = CoreMessageFactory.createCoreMessage(1, persistentMessage, null);      
-         MessageReference ref = ms.reference(msg);         
-         boolean routed = office1.route(ref, new SimpleCondition("topic"), null);         
-         assertTrue(routed);         
-         Thread.sleep(500);         
-         checkContainsAndAcknowledge(msg, receiver1, sub1);
-         this.checkEmpty(receiver2);
-         this.checkEmpty(receiver3);
-         
-         msg = CoreMessageFactory.createCoreMessage(2, persistentMessage, null);      
-         ref = ms.reference(msg);         
-         routed = office2.route(ref, new SimpleCondition("topic"), null);         
-         assertTrue(routed);                  
-         Thread.sleep(500);
-         this.checkEmpty(receiver1);
-         checkContainsAndAcknowledge(msg, receiver2, sub2);
-         this.checkEmpty(receiver3);
-         
-         msg = CoreMessageFactory.createCoreMessage(3, persistentMessage, null);      
-         ref = ms.reference(msg);         
-         routed = office3.route(ref, new SimpleCondition("topic"), null);           
-         assertTrue(routed);         
-         Thread.sleep(500);
-         this.checkEmpty(receiver1);         
-         this.checkEmpty(receiver2);
-         checkContainsAndAcknowledge(msg, receiver3, sub2);           
-                         
-         if (checkNoMessageData())
-         {
-            fail("Message data still in database");
-         }
-         
-      }
-      finally
-      {
-         if (office1 != null)
-         {            
-            office1.stop();
-         }
-         
-         if (office2 != null)
-         {
-            office2.stop();
-         }
-         
-         if (office3 != null)
-         {            
-            office3.stop();
-         }
-         
-      }
-   }
-   
-   
-   
-   /**
-    * We set up a complex scenario with multiple subscriptions, shared and unshared on different
-    * nodes.
-    * 
-    * node1: no subscriptions
-    * node2: 2 non durable
-    * node3: 1 non shared durable, 1 non durable
-    * node4: 1 shared durable (shared1), 1 non shared durable, 3 non durable
-    * node5: 2 shared durable (shared1 and shared2)
-    * node6: 1 shared durable (shared2), 1 non durable
-    * node7: 1 shared durable (shared2)
-    * 
-    * Then we send mess
-    */
-   protected void routeComplexTopic(boolean persistent) throws Throwable
-   {
-      ClusteredPostOffice office1 = null;
-      ClusteredPostOffice office2 = null;
-      ClusteredPostOffice office3 = null;
-      ClusteredPostOffice office4 = null;
-      ClusteredPostOffice office5 = null;
-      ClusteredPostOffice office6 = null;
-      ClusteredPostOffice office7 = null;
-        
-      try
-      {   
-         office1 = createClusteredPostOffice(1, "testgroup", sc, ms, pm, tr);
-         office2 = createClusteredPostOffice(2, "testgroup", sc, ms, pm, tr);
-         office3 = createClusteredPostOffice(3, "testgroup", sc, ms, pm, tr);
-         office4 = createClusteredPostOffice(4, "testgroup", sc, ms, pm, tr);
-         office5 = createClusteredPostOffice(5, "testgroup", sc, ms, pm, tr);
-         office6 = createClusteredPostOffice(6, "testgroup", sc, ms, pm, tr);
-         office7 = createClusteredPostOffice(7, "testgroup", sc, ms, pm, tr);
-         
-         //Node 2
-         //======
-         
-         // Non durable 1 on node 2
-         LocalClusteredQueue nonDurable1 =
-            new LocalClusteredQueue(office2, 2, "nondurable1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-
-         office2.bindClusteredQueue(new SimpleCondition("topic"), nonDurable1);
-         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         nonDurable1.add(receiver1);
-         
-         // Non durable 2 on node 2
-         LocalClusteredQueue nonDurable2 =
-            new LocalClusteredQueue(office2, 2, "nondurable2", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-
-         office2.bindClusteredQueue(new SimpleCondition("topic"), nonDurable2);
-         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         nonDurable2.add(receiver2);
-         
-         //Node 3
-         //======
-         
-         // Non shared durable
-         LocalClusteredQueue nonSharedDurable1 =
-            new LocalClusteredQueue(office3, 3, "nonshareddurable1", channelIDManager.getID(), ms,
-                                    pm, true, true, -1, null, tr);
-
-         office3.bindClusteredQueue(new SimpleCondition("topic"), nonSharedDurable1);
-         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         nonSharedDurable1.add(receiver3);
-         
-         // Non durable
-         LocalClusteredQueue nonDurable3 =
-            new LocalClusteredQueue(office3, 3, "nondurable3", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-
-         office3.bindClusteredQueue(new SimpleCondition("topic"), nonDurable3);
-         SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         nonDurable3.add(receiver4);
-         
-         //Node 4
-         //======
-         
-         // Shared durable
-         LocalClusteredQueue sharedDurable1 =
-            new LocalClusteredQueue(office4, 4, "shareddurable1", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-
-         office4.bindClusteredQueue(new SimpleCondition("topic"), sharedDurable1);
-         SimpleReceiver receiver5 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         sharedDurable1.add(receiver5);
-         
-         // Non shared durable
-         LocalClusteredQueue nonSharedDurable2 =
-            new LocalClusteredQueue(office4, 4, "nonshareddurable2", channelIDManager.getID(), ms,
-                                    pm, true, true, -1, null, tr);
-
-         office4.bindClusteredQueue(new SimpleCondition("topic"), nonSharedDurable2);
-         SimpleReceiver receiver6 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         nonSharedDurable2.add(receiver6);
-         
-         // Non durable
-         LocalClusteredQueue nonDurable4 =
-            new LocalClusteredQueue(office4, 4, "nondurable4", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-
-         office4.bindClusteredQueue(new SimpleCondition("topic"), nonDurable4);
-         SimpleReceiver receiver7 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         nonDurable4.add(receiver7);
-         
-         // Non durable
-         LocalClusteredQueue nonDurable5 =
-            new LocalClusteredQueue(office4, 4, "nondurable5", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office4.bindClusteredQueue(new SimpleCondition("topic"), nonDurable5);
-         SimpleReceiver receiver8 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         nonDurable5.add(receiver8);
-         
-         // Non durable
-         LocalClusteredQueue nonDurable6 =
-            new LocalClusteredQueue(office4, 4, "nondurable6", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office4.bindClusteredQueue(new SimpleCondition("topic"), nonDurable6);
-         SimpleReceiver receiver9 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         nonDurable6.add(receiver9);
-         
-         // Node 5
-         //=======
-         // Shared durable
-         LocalClusteredQueue sharedDurable2 =
-            new LocalClusteredQueue(office5, 5, "shareddurable1", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-
-         office5.bindClusteredQueue(new SimpleCondition("topic"), sharedDurable2);
-         SimpleReceiver receiver10 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         sharedDurable2.add(receiver10);
-         
-         // Shared durable
-         LocalClusteredQueue sharedDurable3 =
-            new LocalClusteredQueue(office5, 5, "shareddurable2", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-
-         office5.bindClusteredQueue(new SimpleCondition("topic"), sharedDurable3);
-         SimpleReceiver receiver11 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         sharedDurable3.add(receiver11);
-         
-         // Node 6
-         //=========
-         LocalClusteredQueue sharedDurable4 =
-            new LocalClusteredQueue(office6, 6, "shareddurable2", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-
-         office6.bindClusteredQueue(new SimpleCondition("topic"), sharedDurable4);
-         SimpleReceiver receiver12 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         sharedDurable4.add(receiver12);
-         
-         LocalClusteredQueue nonDurable7 =
-            new LocalClusteredQueue(office6, 6, "nondurable7", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office6.bindClusteredQueue(new SimpleCondition("topic"), nonDurable7);
-         SimpleReceiver receiver13 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         nonDurable7.add(receiver13);
-         
-         //Node 7
-         //=======
-         LocalClusteredQueue sharedDurable5 =
-            new LocalClusteredQueue(office7, 7, "shareddurable2", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-
-         office7.bindClusteredQueue(new SimpleCondition("topic"), sharedDurable5);
-         SimpleReceiver receiver14 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         sharedDurable5.add(receiver14);
-         
-         
-         //Send 1 message at node1
-         //========================
-         
-         List msgs = sendMessages("topic", persistent, office1, 1, null);
-         
-         //n2
-         checkContainsAndAcknowledge(msgs, receiver1, nonDurable1);
-         checkContainsAndAcknowledge(msgs, receiver2, nonDurable2);
-         
-         //n3
-         checkContainsAndAcknowledge(msgs, receiver3, nonSharedDurable1);
-         checkContainsAndAcknowledge(msgs, receiver4, nonDurable3);
-         
-         //n4
-         checkContainsAndAcknowledge(msgs, receiver5, sharedDurable1);
-         checkContainsAndAcknowledge(msgs, receiver6, nonSharedDurable2);
-         checkContainsAndAcknowledge(msgs, receiver7, nonDurable4);
-         checkContainsAndAcknowledge(msgs, receiver8, nonDurable5);
-         checkContainsAndAcknowledge(msgs, receiver9, nonDurable6);
-         
-         //n5
-         checkEmpty(receiver10);
-         checkContainsAndAcknowledge(msgs, receiver11, sharedDurable3);
-         
-         //n6
-         checkEmpty(receiver12);
-         checkContainsAndAcknowledge(msgs, receiver13, nonDurable7);
-         
-         //n7
-         checkEmpty(receiver14);
-         
-         
-         //Send 1 message at node2
-         //========================
-         
-         msgs = sendMessages("topic", persistent, office2, 1, null);
-         
-         //n2
-         checkContainsAndAcknowledge(msgs, receiver1, nonDurable1);
-         checkContainsAndAcknowledge(msgs, receiver2, nonDurable2);
-         
-         //n3
-         checkContainsAndAcknowledge(msgs, receiver3, nonSharedDurable1);
-         checkContainsAndAcknowledge(msgs, receiver4, nonDurable3);
-         
-         //n4
-         checkContainsAndAcknowledge(msgs, receiver5, sharedDurable1);
-         checkContainsAndAcknowledge(msgs, receiver6, nonSharedDurable2);
-         checkContainsAndAcknowledge(msgs, receiver7, nonDurable4);
-         checkContainsAndAcknowledge(msgs, receiver8, nonDurable5);
-         checkContainsAndAcknowledge(msgs, receiver9, nonDurable6);
-         
-         //n5
-         checkEmpty(receiver10);
-         checkContainsAndAcknowledge(msgs, receiver11, sharedDurable3);
-         
-         //n6
-         checkEmpty(receiver12);
-         checkContainsAndAcknowledge(msgs, receiver13, nonDurable7);
-         
-         //n7
-         checkEmpty(receiver14);
-         
-         //Send 1 message at node3
-         //========================
-         
-         msgs = sendMessages("topic", persistent, office3, 1, null);
-         
-         //n2
-         checkContainsAndAcknowledge(msgs, receiver1, nonDurable1);
-         checkContainsAndAcknowledge(msgs, receiver2, nonDurable2);
-         
-         //n3
-         checkContainsAndAcknowledge(msgs, receiver3, nonSharedDurable1);
-         checkContainsAndAcknowledge(msgs, receiver4, nonDurable3);
-         
-         //n4
-         checkContainsAndAcknowledge(msgs, receiver5, sharedDurable1);
-         checkContainsAndAcknowledge(msgs, receiver6, nonSharedDurable2);
-         checkContainsAndAcknowledge(msgs, receiver7, nonDurable4);
-         checkContainsAndAcknowledge(msgs, receiver8, nonDurable5);
-         checkContainsAndAcknowledge(msgs, receiver9, nonDurable6);
-         
-         //n5
-         checkEmpty(receiver10);
-         checkContainsAndAcknowledge(msgs, receiver11, sharedDurable3);
-         
-         //n6
-         checkEmpty(receiver12);
-         checkContainsAndAcknowledge(msgs, receiver13, nonDurable7);
-         
-         //n7
-         checkEmpty(receiver14);     
-         
-         //Send 1 message at node4
-         //========================
-         
-         msgs = sendMessages("topic", persistent, office4, 1, null);         
-               
-         //n2
-         checkContainsAndAcknowledge(msgs, receiver1, nonDurable1);
-         checkContainsAndAcknowledge(msgs, receiver2, nonDurable2);
-         
-         //n3
-         checkContainsAndAcknowledge(msgs, receiver3, nonSharedDurable1);
-         checkContainsAndAcknowledge(msgs, receiver4, nonDurable3);
-         
-         //n4
-         checkContainsAndAcknowledge(msgs, receiver5, sharedDurable1); // shared durable 1
-         checkContainsAndAcknowledge(msgs, receiver6, nonSharedDurable2);
-         checkContainsAndAcknowledge(msgs, receiver7, nonDurable4);
-         checkContainsAndAcknowledge(msgs, receiver8, nonDurable5);
-         checkContainsAndAcknowledge(msgs, receiver9, nonDurable6);
-         
-         //n5
-         checkEmpty(receiver10);       //shared durable 1
-         checkContainsAndAcknowledge(msgs, receiver11, sharedDurable3);     //shared durable 2    
-         
-         //n6
-         checkEmpty(receiver12); // shared durable 2
-         checkContainsAndAcknowledge(msgs, receiver13, nonDurable7); 
-         
-         //n7
-         checkEmpty(receiver14);
-         
-         //Send 1 message at node5
-         //========================
-         
-         msgs = sendMessages("topic", persistent, office5, 1, null);
-             
-         //n2
-         checkContainsAndAcknowledge(msgs, receiver1, nonDurable1);
-         checkContainsAndAcknowledge(msgs, receiver2, nonDurable2);
-         
-         //n3
-         checkContainsAndAcknowledge(msgs, receiver3, nonSharedDurable1);
-         checkContainsAndAcknowledge(msgs, receiver4, nonDurable3);
-         
-         //n4
-         checkEmpty(receiver5);
-         checkContainsAndAcknowledge(msgs, receiver6, nonSharedDurable2);
-         checkContainsAndAcknowledge(msgs, receiver7, nonDurable4);
-         checkContainsAndAcknowledge(msgs, receiver8, nonDurable5);
-         checkContainsAndAcknowledge(msgs, receiver9, nonDurable6);
-         
-         //n5
-         checkContainsAndAcknowledge(msgs, receiver10, sharedDurable2);
-         checkContainsAndAcknowledge(msgs, receiver11, sharedDurable3);
-         
-         //n6
-         checkEmpty(receiver12);
-         checkContainsAndAcknowledge(msgs, receiver13, nonDurable7);
-         
-         //n7
-         checkEmpty(receiver12);
-         
-         //Send 1 message at node6
-         //========================
-         
-         msgs = sendMessages("topic", persistent, office6, 1, null);
-             
-         //n2
-         checkContainsAndAcknowledge(msgs, receiver1, nonDurable1);
-         checkContainsAndAcknowledge(msgs, receiver2, nonDurable2);
-         
-         //n3
-         checkContainsAndAcknowledge(msgs, receiver3, nonSharedDurable1);
-         checkContainsAndAcknowledge(msgs, receiver4, nonDurable3);
-         
-         //n4
-         checkContainsAndAcknowledge(msgs, receiver5, sharedDurable1);
-         checkContainsAndAcknowledge(msgs, receiver6, nonSharedDurable2);
-         checkContainsAndAcknowledge(msgs, receiver7, nonDurable4);
-         checkContainsAndAcknowledge(msgs, receiver8, nonDurable5);
-         checkContainsAndAcknowledge(msgs, receiver9, nonDurable6);
-         
-         //n5
-         checkEmpty(receiver10);
-        
-         checkEmpty(receiver11);
-         
-         //n6
-         checkContainsAndAcknowledge(msgs, receiver12, sharedDurable4);         
-         checkContainsAndAcknowledge(msgs, receiver13, nonDurable7);
-         
-         //n7
-         checkEmpty(receiver12);
-         
-         //Send 1 message at node7
-         //========================
-         
-         msgs = sendMessages("topic", persistent, office7, 1, null);
-
-         //n2
-         checkContainsAndAcknowledge(msgs, receiver1, nonDurable1);
-         checkContainsAndAcknowledge(msgs, receiver2, nonDurable2);
-         
-         //n3
-         checkContainsAndAcknowledge(msgs, receiver3, nonSharedDurable1);
-         checkContainsAndAcknowledge(msgs, receiver4, nonDurable3);
-         
-         //n4
-         checkContainsAndAcknowledge(msgs, receiver5, sharedDurable1);
-         checkContainsAndAcknowledge(msgs, receiver6, nonSharedDurable2);
-         checkContainsAndAcknowledge(msgs, receiver7, nonDurable4);
-         checkContainsAndAcknowledge(msgs, receiver8, nonDurable5);
-         checkContainsAndAcknowledge(msgs, receiver9, nonDurable6);
-         
-         //n5
-         checkEmpty(receiver10);
-         checkEmpty(receiver11);
-         
-         //n6
-         checkEmpty(receiver12);
-         checkContainsAndAcknowledge(msgs, receiver13, nonDurable7);
-         
-         //n7
-         checkContainsAndAcknowledge(msgs, receiver14, sharedDurable5);
-         
-         if (checkNoMessageData())
-         {
-            fail("Message data still in database");
-         }        
-      }
-      finally
-      {
-         if (office1 != null)
-         {            
-            office1.stop();
-         }
-         
-         if (office2 != null)
-         {
-            office2.stop();
-         }
-         
-         if (office3 != null)
-         {            
-            try
-            {
-               office3.unbindClusteredQueue("nonshareddurable1");
-            }
-            catch (Exception ignore)
-            {   
-               ignore.printStackTrace();
-            }
-            office3.stop();
-         }
-         
-         if (office4 != null)
-         {
-            try
-            {
-               office4.unbindClusteredQueue("shareddurable1");
-               office4.unbindClusteredQueue("nonshareddurable2");
-            }
-            catch (Exception ignore)
-            {           
-               ignore.printStackTrace();
-            }
-            office4.stop();
-         }
-         
-         if (office5 != null)
-         {      
-            try
-            {
-               office5.unbindClusteredQueue("shareddurable1");
-               office5.unbindClusteredQueue("shareddurable2");
-            }
-            catch (Exception ignore)
-            {               
-               ignore.printStackTrace();
-            }
-            office5.stop();
-         }
-         
-         if (office6 != null)
-         {         
-            try
-            {
-               office6.unbindClusteredQueue("shareddurable2");
-            }
-            catch (Exception ignore)
-            {               
-               ignore.printStackTrace();
-            }
-            office6.stop();
-         }
-         
-         if (office7 != null)
-         {      
-            try
-            {
-               office7.unbindClusteredQueue("shareddurable2");
-            }
-            catch (Exception ignore)
-            {               
-               ignore.printStackTrace();
-            }
-            office7.stop();
-         }
-        
-      }
-   }
-   
-   
-
-   
-   
-   protected void clusteredTransactionalRoute(boolean persistent) throws Throwable
-   {
-      ClusteredPostOffice office1 = null;
-      
-      ClusteredPostOffice office2 = null;
-      
-      try
-      {   
-         //Start two offices
-         
-         office1 = createClusteredPostOffice(1, "testgroup", sc, ms, pm, tr);
-         office2 = createClusteredPostOffice(2, "testgroup", sc, ms, pm, tr);
-     
-         LocalClusteredQueue[] queues = new LocalClusteredQueue[16];
-         Binding[] bindings = new Binding[16];
-         
-         queues[0] =
-            new LocalClusteredQueue(office1, 1, "sub1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         bindings[0] = office1.bindClusteredQueue(new SimpleCondition("topic1"), queues[0]);
-         
-         queues[1] =
-            new LocalClusteredQueue(office1, 1, "sub2", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         bindings[1] = office1.bindClusteredQueue(new SimpleCondition("topic1"), queues[1]);
-         
-         queues[2] =
-            new LocalClusteredQueue(office2, 2, "sub3", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         bindings[2] = office2.bindClusteredQueue(new SimpleCondition("topic1"), queues[2]);
-         
-         queues[3] =
-            new LocalClusteredQueue(office2, 2, "sub4", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         bindings[3] = office2.bindClusteredQueue(new SimpleCondition("topic1"), queues[3]);
-         
-         queues[4] =
-            new LocalClusteredQueue(office2, 2, "sub5", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-         bindings[4] = office2.bindClusteredQueue(new SimpleCondition("topic1"), queues[4]);
-         
-         queues[5] =
-            new LocalClusteredQueue(office1, 1, "sub6", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         bindings[5] = office1.bindClusteredQueue(new SimpleCondition("topic1"), queues[5]);
-         
-         queues[6] =
-            new LocalClusteredQueue(office1, 1, "sub7", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-         bindings[6] = office1.bindClusteredQueue(new SimpleCondition("topic1"), queues[6]);
-         
-         queues[7] =
-            new LocalClusteredQueue(office1, 1, "sub8", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-         bindings[7] = office1.bindClusteredQueue(new SimpleCondition("topic1"), queues[7]);
-         
-         queues[8] =
-            new LocalClusteredQueue(office1, 1, "sub9", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         bindings[8] = office1.bindClusteredQueue(new SimpleCondition("topic2"), queues[8]);
-         
-         queues[9] =
-            new LocalClusteredQueue(office1, 1, "sub10", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         bindings[9] = office1.bindClusteredQueue(new SimpleCondition("topic2"), queues[9]);
-         
-         queues[10] =
-            new LocalClusteredQueue(office2, 2, "sub11", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         bindings[10] = office2.bindClusteredQueue(new SimpleCondition("topic2"), queues[10]);
-         
-         queues[11] =
-            new LocalClusteredQueue(office2, 2, "sub12", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         bindings[11] = office2.bindClusteredQueue(new SimpleCondition("topic2"), queues[11]);
-         
-         queues[12] =
-            new LocalClusteredQueue(office2, 2, "sub13", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-         bindings[12] = office2.bindClusteredQueue(new SimpleCondition("topic2"), queues[12]);
-         
-         queues[13] =
-            new LocalClusteredQueue(office1, 1, "sub14", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         bindings[13] = office1.bindClusteredQueue(new SimpleCondition("topic2"), queues[13]);
-         
-         queues[14] =
-            new LocalClusteredQueue(office1, 1, "sub15", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-         bindings[14] = office1.bindClusteredQueue(new SimpleCondition("topic2"), queues[14]);
-         
-         queues[15] =
-            new LocalClusteredQueue(office1, 1, "sub16", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-         bindings[15] = office1.bindClusteredQueue(new SimpleCondition("topic2"), queues[15]);
-
-         SimpleReceiver[] receivers = new SimpleReceiver[16];
-         
-         for (int i = 0; i < 16; i++)
-         {
-            receivers[i] = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-            queues[i].add(receivers[i]);
-         }
-         
-         //First for topic 1
-         
-         Message msg1 = CoreMessageFactory.createCoreMessage(1, persistent, null);;      
-         MessageReference ref1 = ms.reference(msg1);
-         
-         Message msg2 = CoreMessageFactory.createCoreMessage(2, persistent, null);;      
-         MessageReference ref2 = ms.reference(msg2);
-         
-         Transaction tx = tr.createTransaction();
-
-         boolean routed = office1.route(ref1, new SimpleCondition("topic1"), tx);         
-         assertTrue(routed);
-         routed = office1.route(ref2, new SimpleCondition("topic1"), tx);         
-         assertTrue(routed);
-
-         
-         for (int i = 0; i < 16; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         tx.commit();
-         
-         //Messages are sent asych so may take some finite time to arrive
-         Thread.sleep(1000);
-         
-         for (int i = 0; i < 8; i++)
-         {         
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertEquals(2, msgs.size());
-            Message msgRec1 = (Message)msgs.get(0);
-            assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
-            Message msgRec2 = (Message)msgs.get(1);
-            assertEquals(msg2.getMessageID(), msgRec2.getMessageID());            
-            receivers[i].acknowledge(msgRec1, null);
-            receivers[i].acknowledge(msgRec2, null);
-            msgs = queues[i].browse();
-            assertNotNull(msgs);            
-            assertTrue(msgs.isEmpty());                        
-            receivers[i].clear();
-         }
-         
-         for (int i = 8; i < 16; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         msg1 = CoreMessageFactory.createCoreMessage(1, persistent, null);;      
-         ref1 = ms.reference(msg1);
-         
-         msg2 = CoreMessageFactory.createCoreMessage(2, persistent, null);;      
-         ref2 = ms.reference(msg2);
-         
-         tx = tr.createTransaction();
-
-         routed = office1.route(ref1, new SimpleCondition("topic1"), tx);         
-         assertTrue(routed);
-         routed = office1.route(ref2, new SimpleCondition("topic1"), tx);         
-         assertTrue(routed);
-         
-         //Messages are sent asych so may take some finite time to arrive
-         Thread.sleep(1000);         
-         
-         for (int i = 0; i < 16; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         tx.rollback();
-         
-         for (int i = 0; i < 16; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         //Now send some non transactionally
-         
-         msg1 = CoreMessageFactory.createCoreMessage(1, persistent, null);
-         ref1 = ms.reference(msg1);
-         
-         msg2 = CoreMessageFactory.createCoreMessage(2, persistent, null);
-         ref2 = ms.reference(msg2);
-         
-         routed = office1.route(ref1, new SimpleCondition("topic1"), null);         
-         assertTrue(routed);
-         routed = office1.route(ref2, new SimpleCondition("topic1"), null);         
-         assertTrue(routed);
-         
-         //Messages are sent asych so may take some finite time to arrive
-         Thread.sleep(1000);         
-         
-         //And acknowledge transactionally
-         
-         tx = tr.createTransaction();
-         
-         for (int i = 0; i < 8; i++)
-         {         
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertEquals(2, msgs.size());
-            Message msgRec1 = (Message)msgs.get(0);
-            assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
-            Message msgRec2 = (Message)msgs.get(1);
-            assertEquals(msg2.getMessageID(), msgRec2.getMessageID());      
-                        
-            receivers[i].acknowledge(msgRec1, tx);
-            receivers[i].acknowledge(msgRec2, tx);
-             
-            int deliveringCount = queues[i].getDeliveringCount();
-            
-            assertEquals(2, deliveringCount);
-                       
-            receivers[i].clear();
-         }
-         
-         for (int i = 8; i < 16; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         tx.commit();
-         
-         for (int i = 0; i < 16; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         
-         // and the rollback
-         
-         msg1 = CoreMessageFactory.createCoreMessage(1, persistent, null);;      
-         ref1 = ms.reference(msg1);
-         
-         msg2 = CoreMessageFactory.createCoreMessage(2, persistent, null);;      
-         ref2 = ms.reference(msg2);
-         
-         routed = office1.route(ref1, new SimpleCondition("topic1"), null);         
-         assertTrue(routed);
-         routed = office1.route(ref2, new SimpleCondition("topic1"), null);         
-         assertTrue(routed);
-         
-         Thread.sleep(1000);
-                 
-         tx = tr.createTransaction();
-         
-         for (int i = 0; i < 8; i++)
-         {         
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertEquals(2, msgs.size());
-            Message msgRec1 = (Message)msgs.get(0);
-            assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
-            Message msgRec2 = (Message)msgs.get(1);
-            assertEquals(msg2.getMessageID(), msgRec2.getMessageID());      
-                        
-            receivers[i].acknowledge(msgRec1, tx);
-            receivers[i].acknowledge(msgRec2, tx);
-               
-            int deliveringCount = queues[i].getDeliveringCount();
-            
-            assertEquals(2, deliveringCount);
-            
-         }
-         
-         for (int i = 8; i < 16; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         tx.rollback();
-         
-         for (int i = 0; i < 8; i++)
-         {         
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertEquals(2, msgs.size());
-            Message msgRec1 = (Message)msgs.get(0);
-            assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
-            Message msgRec2 = (Message)msgs.get(1);
-            assertEquals(msg2.getMessageID(), msgRec2.getMessageID());      
-                                 
-            int deliveringCount = queues[i].getDeliveringCount();
-            
-            assertEquals(2, deliveringCount);
-            
-            receivers[i].acknowledge(msgRec1, null);
-            receivers[i].acknowledge(msgRec2, null);
-                           
-            receivers[i].clear();
-         }
-         
-         for (int i = 8; i < 16; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         
-         // Now for topic 2
-         
-         msg1 = CoreMessageFactory.createCoreMessage(1, persistent, null);    
-         ref1 = ms.reference(msg1);
-         
-         msg2 = CoreMessageFactory.createCoreMessage(2, persistent, null);     
-         ref2 = ms.reference(msg2);
-         
-         tx = tr.createTransaction();
-
-         routed = office1.route(ref1, new SimpleCondition("topic2"), tx);         
-         assertTrue(routed);
-         routed = office1.route(ref2, new SimpleCondition("topic2"), tx);         
-         assertTrue(routed);
-         
-         
-         
-         for (int i = 0; i < 16; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         tx.commit();
-         
-         //Messages are sent asych so may take some finite time to arrive
-         Thread.sleep(1000);
-         
-         for (int i = 0; i < 8; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         for (int i = 8; i < 16; i++)
-         {         
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertEquals(2, msgs.size());
-            Message msgRec1 = (Message)msgs.get(0);
-            assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
-            Message msgRec2 = (Message)msgs.get(1);
-            assertEquals(msg2.getMessageID(), msgRec2.getMessageID());            
-            receivers[i].acknowledge(msgRec1, null);
-            receivers[i].acknowledge(msgRec2, null);
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty()); 
-            receivers[i].clear();
-         }
-         
-         msg1 = CoreMessageFactory.createCoreMessage(1, persistent, null);;      
-         ref1 = ms.reference(msg1);
-         
-         msg2 = CoreMessageFactory.createCoreMessage(2, persistent, null);;      
-         ref2 = ms.reference(msg2);
-         
-         tx = tr.createTransaction();
-
-         routed = office1.route(ref1, new SimpleCondition("topic1"), tx);         
-         assertTrue(routed);
-         routed = office1.route(ref2, new SimpleCondition("topic1"), tx);         
-         assertTrue(routed);
-         
-         for (int i = 0; i < 16; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         tx.rollback();
-         
-         for (int i = 0; i < 16; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         //Now send some non transactionally
-         
-         msg1 = CoreMessageFactory.createCoreMessage(1, persistent, null);      
-         ref1 = ms.reference(msg1);
-         
-         msg2 = CoreMessageFactory.createCoreMessage(2, persistent, null);      
-         ref2 = ms.reference(msg2);
-         
-         routed = office1.route(ref1, new SimpleCondition("topic2"), null);         
-         assertTrue(routed);
-         routed = office1.route(ref2, new SimpleCondition("topic2"), null);         
-         assertTrue(routed);
-         
-         Thread.sleep(1000);
-         
-         //And acknowledge transactionally
-         
-         tx = tr.createTransaction();
-         
-         for (int i = 0; i < 8; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         for (int i = 8; i < 16; i++)
-         {         
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertEquals(2, msgs.size());
-            Message msgRec1 = (Message)msgs.get(0);
-            assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
-            Message msgRec2 = (Message)msgs.get(1);
-            assertEquals(msg2.getMessageID(), msgRec2.getMessageID());      
-                        
-            receivers[i].acknowledge(msgRec1, tx);
-            receivers[i].acknowledge(msgRec2, tx);
-                        
-            int deliveringCount = queues[i].getDeliveringCount();
-            
-            assertEquals(2, deliveringCount);
-            
-            receivers[i].clear();
-         }
-         
-         
-         
-         tx.commit();
-         
-         for (int i = 0; i < 16; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         
-         // and the rollback
-         
-         msg1 = CoreMessageFactory.createCoreMessage(1, persistent, null);;      
-         ref1 = ms.reference(msg1);
-         
-         msg2 = CoreMessageFactory.createCoreMessage(2, persistent, null);;      
-         ref2 = ms.reference(msg2);
-         
-         routed = office1.route(ref1, new SimpleCondition("topic2"), null);         
-         assertTrue(routed);
-         routed = office1.route(ref2, new SimpleCondition("topic2"), null);         
-         assertTrue(routed);
-         
-         Thread.sleep(1000);
-          
-         tx = tr.createTransaction();
-         
-         for (int i = 0; i < 8; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         for (int i = 8; i < 16; i++)
-         {         
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertEquals(2, msgs.size());
-            Message msgRec1 = (Message)msgs.get(0);
-            assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
-            Message msgRec2 = (Message)msgs.get(1);
-            assertEquals(msg2.getMessageID(), msgRec2.getMessageID());      
-            
-            
-            receivers[i].acknowledge(msgRec1, tx);
-            receivers[i].acknowledge(msgRec2, tx);
-            
-            
-            int deliveringCount = queues[i].getDeliveringCount();
-            
-            assertEquals(2, deliveringCount);
-         }
-         
-         
-         
-         tx.rollback();
-         
-         for (int i = 0; i < 8; i++)
-         {
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-            msgs = queues[i].browse();
-            assertNotNull(msgs);
-            assertTrue(msgs.isEmpty());
-         }
-         
-         for (int i = 8; i < 16; i++)
-         {         
-            List msgs = receivers[i].getMessages();
-            assertNotNull(msgs);
-            assertEquals(2, msgs.size());
-            Message msgRec1 = (Message)msgs.get(0);
-            assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
-            Message msgRec2 = (Message)msgs.get(1);
-            assertEquals(msg2.getMessageID(), msgRec2.getMessageID());      
-                                              
-            int deliveringCount = queues[i].getDeliveringCount();
-            
-            assertEquals(2, deliveringCount);
-            
-            receivers[i].acknowledge(msgRec1, null);
-            receivers[i].acknowledge(msgRec2, null);             
-            
-            receivers[i].clear();
-         }
-         if (checkNoMessageData())
-         {
-            fail("Message data still in database");
-         }
-      }
-      finally
-      {
-         if (office1 != null)
-         {
-            try
-            {
-               office1.unbindClusteredQueue("sub7");
-               office1.unbindClusteredQueue("sub8");           
-               office1.unbindClusteredQueue("sub15");
-               office1.unbindClusteredQueue("sub16");
-            }
-            catch (Exception ignore)
-            {
-               ignore.printStackTrace();
-            }
-                        
-            office1.stop();
-         }
-         
-         if (office2 != null)
-         {
-            try
-            {
-               office2.unbindClusteredQueue("sub5");
-               office2.unbindClusteredQueue("sub13");
-            }
-            catch (Exception ignore)
-            {
-               ignore.printStackTrace();
-            }
-            
-            office2.stop();
-         }
-      }
-   }
-   
-   protected void setUp() throws Exception
-   {
-      super.setUp();
-   }
-
-   protected void tearDown() throws Exception
-   {
-      super.tearDown();
-   }
-
-   // Private --------------------------------------------------------------------------------------
-
-   // Inner classes --------------------------------------------------------------------------------
-
-}
-
-
-

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeWithDefaultRouterTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeWithDefaultRouterTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeWithDefaultRouterTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,380 +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.postoffice.cluster;
-
-import java.util.List;
-
-import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
-import org.jboss.messaging.core.plugin.postoffice.cluster.LocalClusteredQueue;
-import org.jboss.test.messaging.core.SimpleCondition;
-import org.jboss.test.messaging.core.SimpleReceiver;
-import org.jboss.test.messaging.core.plugin.base.PostOfficeTestBase;
-
-/**
- * 
- * A DefaultClusteredPostOfficeWithDefaultRouterTest
- *
- * @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$</tt>
- *
- * $Id$
- *
- */
-public class DefaultClusteredPostOfficeWithDefaultRouterTest extends PostOfficeTestBase
-{
-   // Constants ------------------------------------------------------------------------------------
-
-   // Static ---------------------------------------------------------------------------------------
-   
-   // Attributes -----------------------------------------------------------------------------------
-    
-   // Constructors ---------------------------------------------------------------------------------
-
-   public DefaultClusteredPostOfficeWithDefaultRouterTest(String name)
-   {
-      super(name);
-   }
-
-   // Public ---------------------------------------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-   }
-
-   public void tearDown() throws Exception
-   {      
-      super.tearDown();
-   }
-   
-   public void testNotLocalPersistent() throws Throwable
-   {
-      notLocal(true);
-   }
-   
-   public void testNotLocalNonPersistent() throws Throwable
-   {
-      notLocal(false);
-   }
-   
-   public void testLocalPersistent() throws Throwable
-   {
-      local(true);
-   }
-   
-   public void testLocalNonPersistent() throws Throwable
-   {
-      local(false);
-   }
-   
-   protected void notLocal(boolean persistent) throws Throwable
-   {
-      ClusteredPostOffice office1 = null;
-      
-      ClusteredPostOffice office2 = null;
-      
-      ClusteredPostOffice office3 = null;
-      
-      ClusteredPostOffice office4 = null;
-      
-      ClusteredPostOffice office5 = null;
-      
-      ClusteredPostOffice office6 = null;
-          
-      try
-      {   
-         office1 = createClusteredPostOffice(1, "testgroup", sc, ms, pm, tr);
-         
-         office2 = createClusteredPostOffice(2, "testgroup", sc, ms, pm, tr);
-         
-         office3 = createClusteredPostOffice(3, "testgroup", sc, ms, pm, tr);
-         
-         office4 = createClusteredPostOffice(4, "testgroup", sc, ms, pm, tr);
-         
-         office5 = createClusteredPostOffice(5, "testgroup", sc, ms, pm, tr);
-         
-         office6 = createClusteredPostOffice(6, "testgroup", sc, ms, pm, tr);
-         
-         LocalClusteredQueue queue1 =
-            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office2.bindClusteredQueue(new SimpleCondition("topic"), queue1);
-         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue1.add(receiver1);
-         
-         LocalClusteredQueue queue2 =
-            new LocalClusteredQueue(office3, 3, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office3.bindClusteredQueue(new SimpleCondition("topic"), queue2);
-         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue2.add(receiver2);
-         
-         LocalClusteredQueue queue3 =
-            new LocalClusteredQueue(office4, 4, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office4.bindClusteredQueue(new SimpleCondition("topic"), queue3);
-         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue3.add(receiver3);
-         
-         LocalClusteredQueue queue4 =
-            new LocalClusteredQueue(office5, 5, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office5.bindClusteredQueue(new SimpleCondition("topic"), queue4);
-         SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue4.add(receiver4);
-         
-         LocalClusteredQueue queue5 =
-            new LocalClusteredQueue(office6, 6, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office6.bindClusteredQueue(new SimpleCondition("topic"), queue5);
-         SimpleReceiver receiver5 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue5.add(receiver5);
-               
-         List msgs = sendMessages("topic", persistent, office1, 1, null);         
-         checkContainsAndAcknowledge(msgs, receiver1, queue1);         
-         checkEmpty(receiver2);
-         checkEmpty(receiver3);
-         checkEmpty(receiver4);
-         checkEmpty(receiver5);
-         
-         msgs = sendMessages("topic", persistent, office1, 1, null);         
-         checkEmpty(receiver1);
-         checkContainsAndAcknowledge(msgs, receiver2, queue1);                  
-         checkEmpty(receiver3);
-         checkEmpty(receiver4);
-         checkEmpty(receiver5);
-         
-         msgs = sendMessages("topic", persistent, office1, 1, null);         
-         checkEmpty(receiver1);
-         checkEmpty(receiver2);
-         checkContainsAndAcknowledge(msgs, receiver3, queue1);                           
-         checkEmpty(receiver4);
-         checkEmpty(receiver5);
-         
-         msgs = sendMessages("topic", persistent, office1, 1, null);         
-         checkEmpty(receiver1);
-         checkEmpty(receiver2);
-         checkEmpty(receiver3);
-         checkContainsAndAcknowledge(msgs, receiver4, queue1);                                    
-         checkEmpty(receiver5);
-         
-         msgs = sendMessages("topic", persistent, office1, 1, null);         
-         checkEmpty(receiver1);
-         checkEmpty(receiver2);
-         checkEmpty(receiver3);
-         checkEmpty(receiver4);
-         checkContainsAndAcknowledge(msgs, receiver5, queue1); 
-         
-         msgs = sendMessages("topic", persistent, office1, 1, null);         
-         checkContainsAndAcknowledge(msgs, receiver1, queue1);         
-         checkEmpty(receiver2);
-         checkEmpty(receiver3);
-         checkEmpty(receiver4);
-         checkEmpty(receiver5);
-         
-         msgs = sendMessages("topic", persistent, office1, 1, null);         
-         checkEmpty(receiver1);
-         checkContainsAndAcknowledge(msgs, receiver2, queue1);                  
-         checkEmpty(receiver3);
-         checkEmpty(receiver4);
-         checkEmpty(receiver5);
-         
-                     
-      }
-      finally
-      {
-         if (office1 != null)
-         {            
-            office1.stop();
-         }
-         
-         if (office2 != null)
-         {
-            office2.stop();
-         }
-         
-         if (office3 != null)
-         {            
-            office3.stop();
-         }
-         
-         if (office4 != null)
-         {
-            office4.stop();
-         }
-         
-         if (office5 != null)
-         {            
-            office5.stop();
-         }
-         
-         if (office6 != null)
-         {
-            office6.stop();
-         }
-      }
-   }
-   
-   
-   
-   
-   protected void local(boolean persistent) throws Throwable
-   {
-      ClusteredPostOffice office1 = null;
-      ClusteredPostOffice office2 = null;
-      ClusteredPostOffice office3 = null;
-      ClusteredPostOffice office4 = null;
-      ClusteredPostOffice office5 = null;
-      ClusteredPostOffice office6 = null;
-          
-      try
-      {   
-         office1 = createClusteredPostOffice(1, "testgroup", sc, ms, pm, tr);
-         office2 = createClusteredPostOffice(2, "testgroup", sc, ms, pm, tr);
-         office3 = createClusteredPostOffice(3, "testgroup", sc, ms, pm, tr);
-         office4 = createClusteredPostOffice(4, "testgroup", sc, ms, pm, tr);
-         office5 = createClusteredPostOffice(5, "testgroup", sc, ms, pm, tr);
-         office6 = createClusteredPostOffice(6, "testgroup", sc, ms, pm, tr);
-         
-         LocalClusteredQueue queue1 =
-            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office2.bindClusteredQueue(new SimpleCondition("topic"), queue1);
-         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue1.add(receiver1);
-         
-         LocalClusteredQueue queue2 =
-            new LocalClusteredQueue(office3, 3, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office3.bindClusteredQueue(new SimpleCondition("topic"), queue2);
-         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue2.add(receiver2);
-         
-         LocalClusteredQueue queue3 =
-            new LocalClusteredQueue(office4, 4, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office4.bindClusteredQueue(new SimpleCondition("topic"), queue3);
-         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue3.add(receiver3);
-         
-         LocalClusteredQueue queue4 =
-            new LocalClusteredQueue(office5, 5, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office5.bindClusteredQueue(new SimpleCondition("topic"), queue4);
-         SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue4.add(receiver4);
-         
-         LocalClusteredQueue queue5 =
-            new LocalClusteredQueue(office6, 6, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office6.bindClusteredQueue(new SimpleCondition("topic"), queue5);
-         SimpleReceiver receiver5 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue5.add(receiver5);
-               
-         List msgs = sendMessages("topic", persistent, office2, 3, null);         
-         checkContainsAndAcknowledge(msgs, receiver1, queue1);         
-         checkEmpty(receiver2);
-         checkEmpty(receiver3);
-         checkEmpty(receiver4);
-         checkEmpty(receiver5);
-         
-         msgs = sendMessages("topic", persistent, office2, 3, null);         
-         checkContainsAndAcknowledge(msgs, receiver1, queue1);         
-         checkEmpty(receiver2);
-         checkEmpty(receiver3);
-         checkEmpty(receiver4);
-         checkEmpty(receiver5);
-         
-         msgs = sendMessages("topic", persistent, office2, 3, null);         
-         checkContainsAndAcknowledge(msgs, receiver1, queue1);         
-         checkEmpty(receiver2);
-         checkEmpty(receiver3);
-         checkEmpty(receiver4);
-         checkEmpty(receiver5);
-         
-         
-         msgs = sendMessages("topic", persistent, office3, 3, null); 
-         checkEmpty(receiver1);
-         checkContainsAndAcknowledge(msgs, receiver2, queue1);                  
-         checkEmpty(receiver3);
-         checkEmpty(receiver4);
-         checkEmpty(receiver5);
-         
-         msgs = sendMessages("topic", persistent, office3, 3, null); 
-         checkEmpty(receiver1);
-         checkContainsAndAcknowledge(msgs, receiver2, queue1);                  
-         checkEmpty(receiver3);
-         checkEmpty(receiver4);
-         checkEmpty(receiver5);
-         
-         msgs = sendMessages("topic", persistent, office3, 3, null); 
-         checkEmpty(receiver1);
-         checkContainsAndAcknowledge(msgs, receiver2, queue1);                  
-         checkEmpty(receiver3);
-         checkEmpty(receiver4);
-         checkEmpty(receiver5);
-         
-                     
-      }
-      finally
-      {
-         if (office1 != null)
-         {            
-            office1.stop();
-         }
-         
-         if (office2 != null)
-         {
-            office2.stop();
-         }
-         
-         if (office3 != null)
-         {            
-            office3.stop();
-         }
-         
-         if (office4 != null)
-         {
-            office4.stop();
-         }
-         
-         if (office5 != null)
-         {            
-            office5.stop();
-         }
-         
-         if (office6 != null)
-         {
-            office6.stop();
-         }
-      }
-   }
-   
-   // Private --------------------------------------------------------------------------------------
-
-   // Inner classes --------------------------------------------------------------------------------
-
-}
-
-
-

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeWithRoundRobinRouterTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeWithRoundRobinRouterTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeWithRoundRobinRouterTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,309 +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.postoffice.cluster;
-
-import java.util.List;
-
-import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
-import org.jboss.messaging.core.plugin.postoffice.cluster.LocalClusteredQueue;
-import org.jboss.test.messaging.core.SimpleCondition;
-import org.jboss.test.messaging.core.SimpleReceiver;
-import org.jboss.test.messaging.core.plugin.base.PostOfficeTestBase;
-
-/**
- * 
- * A DefaultClusteredPostOfficeWithRoundRobinRouterTest
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-public class DefaultClusteredPostOfficeWithRoundRobinRouterTest extends PostOfficeTestBase
-{
-   // Constants ------------------------------------------------------------------------------------
-
-   // Static ---------------------------------------------------------------------------------------
-   
-   // Attributes -----------------------------------------------------------------------------------
-    
-   // Constructors ---------------------------------------------------------------------------------
-
-   public DefaultClusteredPostOfficeWithRoundRobinRouterTest(String name)
-   {
-      super(name);
-   }
-
-   // Public ---------------------------------------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-   }
-
-   public void tearDown() throws Exception
-   {      
-      super.tearDown();
-   }
-   
-   public void testNotLocalPersistent() throws Throwable
-   {
-      notLocal(true);
-   }
-   
-   public void testNotLocalNonPersistent() throws Throwable
-   {
-      notLocal(false);
-   }
-   
-   
-   protected void notLocal(boolean persistent) throws Throwable
-   {
-      log.info("not local:" + persistent);
-      
-      ClusteredPostOffice office1 = null;
-      
-      ClusteredPostOffice office2 = null;
-      
-      ClusteredPostOffice office3 = null;
-      
-      ClusteredPostOffice office4 = null;
-      
-      ClusteredPostOffice office5 = null;
-      
-      ClusteredPostOffice office6 = null;
-          
-      try
-      {   
-         office1 = createClusteredPostOfficeWithRRR(1, "testgroup", sc, ms, pm, tr);
-         
-         office2 = createClusteredPostOfficeWithRRR(2, "testgroup", sc, ms, pm, tr);
-         
-         office3 = createClusteredPostOfficeWithRRR(3, "testgroup", sc, ms, pm, tr);
-         
-         office4 = createClusteredPostOfficeWithRRR(4, "testgroup", sc, ms, pm, tr);
-         
-         office5 = createClusteredPostOfficeWithRRR(5, "testgroup", sc, ms, pm, tr);
-         
-         office6 = createClusteredPostOfficeWithRRR(6, "testgroup", sc, ms, pm, tr);
-         
-         LocalClusteredQueue queue1 =
-            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office1.bindClusteredQueue(new SimpleCondition("topic"), queue1);
-         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue1.add(receiver1);
-         
-         LocalClusteredQueue queue2 =
-            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office2.bindClusteredQueue(new SimpleCondition("topic"), queue2);
-         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue2.add(receiver2);
-         
-         LocalClusteredQueue queue3 =
-            new LocalClusteredQueue(office3, 3, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office3.bindClusteredQueue(new SimpleCondition("topic"), queue3);
-         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue3.add(receiver3);
-         
-         LocalClusteredQueue queue4 =
-            new LocalClusteredQueue(office4, 4, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office4.bindClusteredQueue(new SimpleCondition("topic"), queue4);
-         SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue4.add(receiver4);
-         
-         LocalClusteredQueue queue5 =
-            new LocalClusteredQueue(office5, 5, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office5.bindClusteredQueue(new SimpleCondition("topic"), queue5);
-         SimpleReceiver receiver5 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue5.add(receiver5);
-         
-         LocalClusteredQueue queue6 =
-            new LocalClusteredQueue(office6, 6, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, false, -1, null, tr);
-         office6.bindClusteredQueue(new SimpleCondition("topic"), queue6);
-         SimpleReceiver receiver6 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue6.add(receiver6);
-         
-         log.info("setup");
-               
-         List msgs = sendMessages("topic", persistent, office1, 1, null);         
-         checkContainsAndAcknowledge(msgs, receiver1, queue1);         
-         checkEmpty(receiver2);
-         checkEmpty(receiver3);
-         checkEmpty(receiver4);
-         checkEmpty(receiver5);
-         checkEmpty(receiver6);
-         
-         log.info("1");
-         
-         msgs = sendMessages("topic", persistent, office1, 1, null);         
-         checkEmpty(receiver1);
-         checkContainsAndAcknowledge(msgs, receiver2, queue1);                  
-         checkEmpty(receiver3);
-         checkEmpty(receiver4);
-         checkEmpty(receiver5);
-         checkEmpty(receiver6);
-         
-         log.info("2");
-         
-         
-         msgs = sendMessages("topic", persistent, office1, 1, null);         
-         checkEmpty(receiver1);
-         checkEmpty(receiver2);
-         checkContainsAndAcknowledge(msgs, receiver3, queue1);                           
-         checkEmpty(receiver4);
-         checkEmpty(receiver5);
-         checkEmpty(receiver6);
-         
-         log.info("3");
-         
-         msgs = sendMessages("topic", persistent, office1, 1, null);         
-         checkEmpty(receiver1);
-         checkEmpty(receiver2);
-         checkEmpty(receiver3);
-         checkContainsAndAcknowledge(msgs, receiver4, queue1);                                    
-         checkEmpty(receiver5);
-         checkEmpty(receiver6);
-         
-         
-         
-         log.info("4");
-         msgs = sendMessages("topic", persistent, office1, 1, null);         
-         checkEmpty(receiver1);
-         checkEmpty(receiver2);
-         checkEmpty(receiver3);
-         checkEmpty(receiver4);
-         checkContainsAndAcknowledge(msgs, receiver5, queue1); 
-         checkEmpty(receiver6);
-         
-         
-         log.info("5");
-         msgs = sendMessages("topic", persistent, office1, 1, null);         
-         checkEmpty(receiver1);       
-         checkEmpty(receiver2);
-         checkEmpty(receiver3);
-         checkEmpty(receiver4);
-         checkEmpty(receiver5);
-         checkContainsAndAcknowledge(msgs, receiver6, queue1); 
-         
-         log.info("6");
-         
-         msgs = sendMessages("topic", persistent, office1, 1, null);         
-         checkContainsAndAcknowledge(msgs, receiver1, queue1);      
-         checkEmpty(receiver2);
-         checkEmpty(receiver3);
-         checkEmpty(receiver4);
-         checkEmpty(receiver5);
-         checkEmpty(receiver6);
-         log.info("7");
-                     
-      }
-      finally
-      {
-         if (office1 != null)
-         {            
-            try
-            {
-               office1.stop();
-            }
-            catch (Exception ignore)
-            {
-               
-            }
-         }
-         
-         if (office2 != null)
-         {
-            try
-            {
-               office2.stop();
-            }
-            catch (Exception ignore)
-            {
-               
-            }
-         }
-         
-         if (office3 != null)
-         {            
-            try
-            {
-               office3.stop();
-            }
-            catch (Exception ignore)
-            {
-               
-            }
-         }
-         
-         if (office4 != null)
-         {
-            try
-            {
-               office4.stop();
-            }
-            catch (Exception ignore)
-            {
-               
-            }
-         }
-         
-         if (office5 != null)
-         {            
-            try
-            {
-               office5.stop();
-            }
-            catch (Exception ignore)
-            {
-               
-            }
-         }
-         
-         if (office6 != null)
-         {
-            try
-            {
-               office6.stop();
-            }
-            catch (Exception ignore)
-            {
-               
-            }
-         }
-      }
-   }
-   
-   // Private --------------------------------------------------------------------------------------
-
-   // Inner classes --------------------------------------------------------------------------------
-
-}
-
-
-

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultMessagePullPolicyTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultMessagePullPolicyTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultMessagePullPolicyTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -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.plugin.postoffice.cluster;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.DeliveryObserver;
-import org.jboss.messaging.core.Filter;
-import org.jboss.messaging.core.Receiver;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.postoffice.cluster.ClusteredQueue;
-import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultMessagePullPolicy;
-import org.jboss.messaging.core.plugin.postoffice.cluster.MessagePullPolicy;
-import org.jboss.messaging.core.plugin.postoffice.cluster.QueueStats;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.test.messaging.tools.ServerManagement;
-import org.jboss.test.messaging.tools.jmx.ServiceContainer;
-
-
-public class DefaultMessagePullPolicyTest extends MessagingTestCase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-   protected ServiceContainer sc;
-
-   // Constructors --------------------------------------------------
-
-   public DefaultMessagePullPolicyTest(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-
-      sc = new ServiceContainer("all");
-      
-      sc.start();                
-    
-      log.debug("setup done");
-   }
-
-   public void tearDown() throws Exception
-   {      
-      if (!ServerManagement.isRemote())
-      {
-         sc.stop();
-         sc = null;
-      }
-
-      super.tearDown();
-   }
-   
-   public void test1() throws Exception
-   {
-      MessagePullPolicy policy = new DefaultMessagePullPolicy();
-      
-      List queues = new ArrayList();
-      
-      ClusteredQueue queue1 = new DummyClusteredQueue(true, "queue1", 1000);
-      
-      queues.add(queue1);
-      
-      ClusteredQueue queue2 = new DummyClusteredQueue(false, "queue2", 435);
-      
-      queues.add(queue2);
-      
-      ClusteredQueue queue3 = new DummyClusteredQueue(false, "queue3", 12);
-      
-      queues.add(queue3);
-      
-      ClusteredQueue queue4 = new DummyClusteredQueue(false, "queue4", 900);
-      
-      queues.add(queue4);
-      
-      ClusteredQueue queue5 = new DummyClusteredQueue(false, "queue5", 0);
-      
-      queues.add(queue5);
-      
-      ClusteredQueue chosen = policy.chooseQueue(queues);
-      
-      assertTrue(chosen == queue4);
-   }
-   
-   public void test2() throws Exception
-   {
-      MessagePullPolicy policy = new DefaultMessagePullPolicy();
-      
-      List queues = new ArrayList();
-      
-      ClusteredQueue queue1 = new DummyClusteredQueue(true, "queue1", 0);
-      
-      queues.add(queue1);
-      
-      ClusteredQueue queue2 = new DummyClusteredQueue(false, "queue2", 0);
-      
-      queues.add(queue2);
-      
-      ClusteredQueue queue3 = new DummyClusteredQueue(false, "queue3", 0);
-      
-      queues.add(queue3);
-      
-      ClusteredQueue queue4 = new DummyClusteredQueue(false, "queue4", 0);
-      
-      queues.add(queue4);
-      
-      ClusteredQueue queue5 = new DummyClusteredQueue(false, "queue5", 0);
-      
-      queues.add(queue5);
-      
-      ClusteredQueue chosen = policy.chooseQueue(queues);
-      
-      assertNull(chosen);
-   }
-   
-   public void test3() throws Exception
-   {
-      MessagePullPolicy policy = new DefaultMessagePullPolicy();
-      
-      List queues = new ArrayList();
-      
-      ClusteredQueue queue1 = new DummyClusteredQueue(true, "queue1", 0);
-      
-      queues.add(queue1);           
-      
-      ClusteredQueue chosen = policy.chooseQueue(queues);
-      
-      assertNull(chosen);
-   }
-   
-   public void test4() throws Exception
-   {
-      MessagePullPolicy policy = new DefaultMessagePullPolicy();
-      
-      List queues = new ArrayList();               
-      
-      ClusteredQueue chosen = policy.chooseQueue(queues);
-      
-      assertNull(chosen);
-   }
-   
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-   
-   class DummyClusteredQueue implements ClusteredQueue
-   {
-      private boolean local;
-      
-      private String queueName;
-      
-      private int msgCount;
-      
-      DummyClusteredQueue(boolean local, String queueName, int msgCount)
-      {
-         this.local = local;
-         this.queueName = queueName;
-         this.msgCount = msgCount;
-      }
-
-      public int getNodeId()
-      {
-         // TODO Auto-generated method stub
-         return -1;
-      }
-
-      public QueueStats getStats()
-      {
-         return new QueueStats(queueName, msgCount);
-      }
-
-      public boolean isLocal()
-      {
-         return local;
-      }
-
-      public Filter getFilter()
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public String getName()
-      {
-         return queueName;
-      }
-
-      public boolean isClustered()
-      {
-         return true;
-      }
-
-      public void acknowledge(Delivery d, Transaction tx) throws Throwable
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public void cancel(Delivery d) throws Throwable
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public boolean acceptReliableMessages()
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public void activate()
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public List browse()
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public List browse(Filter filter)
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public void clear()
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public void close()
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public void deactivate()
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public void deliver()
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public List delivering(Filter filter)
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public long getChannelID()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public boolean isActive()
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public boolean isRecoverable()
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public void load() throws Exception
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public int getMessageCount()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public void removeAllReferences() throws Throwable
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public List undelivered(Filter filter)
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public void unload() throws Exception
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public Delivery handle(DeliveryObserver observer, MessageReference reference, Transaction tx)
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public boolean add(Receiver receiver)
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public boolean contains(Receiver receiver)
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public Iterator iterator()
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public int getNumberOfReceivers()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public boolean remove(Receiver receiver)
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public List recoverDeliveries(List messageIds)
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public void addDelivery(Delivery del)
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public int getDeliveringCount()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public int getMaxSize()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public int getMessagesAdded()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public void setMaxSize(int newSize)
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public int getScheduledCount()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-      
-   }
-
-}
-
-

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultRouterTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultRouterTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultRouterTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,591 +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.postoffice.cluster;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.DeliveryObserver;
-import org.jboss.messaging.core.Filter;
-import org.jboss.messaging.core.Receiver;
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.postoffice.cluster.ClusterRouter;
-import org.jboss.messaging.core.plugin.postoffice.cluster.ClusteredQueue;
-import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultRouter;
-import org.jboss.messaging.core.plugin.postoffice.cluster.QueueStats;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.test.messaging.core.SimpleReceiver;
-import org.jboss.test.messaging.core.plugin.base.PostOfficeTestBase;
-import org.jboss.test.messaging.util.CoreMessageFactory;
-
-/**
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- * 
- * TODO Need to add tests for failed over queues to this
- *
- * $Id$
- *
- */
-public class DefaultRouterTest extends PostOfficeTestBase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-   
-   // Constructors --------------------------------------------------
-
-   public DefaultRouterTest(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-   }
-
-   public void tearDown() throws Exception
-   {      
-      super.tearDown();
-   }
-   
-   public void testSize() throws Exception
-   {
-      DefaultRouter dr = new DefaultRouter();
-      
-      ClusteredQueue queue1 = new SimpleQueue(true);
-      dr.add(queue1);
-      
-      assertEquals(1, dr.getNumberOfReceivers());
-      assertEquals(1, dr.getQueues().size());
-      
-      ClusteredQueue queue2 = new SimpleQueue(false);
-      dr.add(queue2);
-      
-      assertEquals(2, dr.getNumberOfReceivers());
-      assertEquals(2, dr.getQueues().size());
-      
-      ClusteredQueue queue3 = new SimpleQueue(false);
-      dr.add(queue3);
-      
-      assertEquals(3, dr.getNumberOfReceivers());
-      assertEquals(3, dr.getQueues().size());
-      
-      dr.remove(queue3);
-      
-      assertEquals(2, dr.getNumberOfReceivers());
-      assertEquals(2, dr.getQueues().size());
-      
-      dr.remove(queue2);
-      
-      assertEquals(1, dr.getNumberOfReceivers());
-      assertEquals(1, dr.getQueues().size());
-      
-      dr.remove(queue1);
-      
-      assertEquals(0, dr.getNumberOfReceivers());
-      assertTrue(dr.getQueues().isEmpty());
-      
-   }
-   
-   // The router only has a local queue
-   public void testRouterOnlyLocal() throws Exception
-   {
-      DefaultRouter dr = new DefaultRouter();
-                    
-      ClusteredQueue queue = new SimpleQueue(true);
-      
-      SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      queue.add(receiver1);
-               
-      dr.add(queue);
-      
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver1);
-   }
-   
-   //The router has only one non local queues
-   public void testRouterOnlyOneNonLocal() throws Exception
-   {
-      DefaultRouter dr = new DefaultRouter();
-                    
-      ClusteredQueue queue = new SimpleQueue(false);
-      
-      SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      queue.add(receiver1);
-      
-      dr.add(queue);
-      
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver1);              
-   }
-   
-   //The router has multiple non local queues and no local queue
-   public void testRouterMultipleNonLocal() throws Exception
-   {
-      DefaultRouter dr = new DefaultRouter();
-                   
-      ClusteredQueue remote1 = new SimpleQueue(false);
-     
-      SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      remote1.add(receiver1);
-      
-      dr.add(remote1);
-      
-      
-      ClusteredQueue remote2 = new SimpleQueue(false);
-      
-      SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      remote2.add(receiver2);
-      
-      dr.add(remote2);
-      
-      
-      ClusteredQueue remote3 = new SimpleQueue(false);
-      
-      SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      remote3.add(receiver3);
-      
-      dr.add(remote3);
-      
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver2);
-      
-      sendAndCheck(dr, receiver3);
-      
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver2);
-      
-      sendAndCheck(dr, receiver3);
-   }
-   
-   
-   // The router has one local with consumer and one non local queue with consumer
-   public void testRouterOneLocalOneNonLocal() throws Exception
-   {
-      DefaultRouter dr = new DefaultRouter();
-                             
-      ClusteredQueue remote1 = new SimpleQueue(false);
-     
-      SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      remote1.add(receiver1);
-      
-      dr.add(remote1);
-      
-      ClusteredQueue queue = new SimpleQueue(true);
-      
-      SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      queue.add(receiver2);
-      
-      dr.add(queue);
-
-      sendAndCheck(dr, receiver2);
-      
-      sendAndCheck(dr, receiver2);
-      
-      sendAndCheck(dr, receiver2);                  
-   }
-   
-   // The router has multiple non local queues with consumers and one local queue
-   public void testRouterMultipleNonLocalOneLocal() throws Exception
-   {
-      DefaultRouter dr = new DefaultRouter();            
-                  
-      ClusteredQueue remote1 = new SimpleQueue(false);
-      
-      SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      remote1.add(receiver1);
-      
-      dr.add(remote1);
-      
-      
-      ClusteredQueue remote2 = new SimpleQueue(false);
-      
-      SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      remote2.add(receiver2);
-      
-      dr.add(remote2);
-      
-      
-      ClusteredQueue remote3 = new SimpleQueue(false);
-      
-      SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      remote3.add(receiver3);
-      
-      dr.add(remote3);
-      
-      
-      ClusteredQueue queue = new SimpleQueue(true);
-            
-      SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      queue.add(receiver4);
-      
-      dr.add(queue);
-      
-      
-      sendAndCheck(dr, receiver4);
-      
-      sendAndCheck(dr, receiver4);
-      
-      sendAndCheck(dr, receiver4);
-   }
-   
-   private long nextId;
-   
-   private void sendAndCheck(ClusterRouter router, SimpleReceiver receiver) throws Exception
-   {
-      Message msg = CoreMessageFactory.createCoreMessage(nextId++, false, null);      
-      
-      MessageReference ref = ms.reference(msg);         
-      
-      Delivery del = router.handle(null, ref, null);
-      
-      assertNotNull(del);
-      
-      assertTrue(del.isSelectorAccepted());
-            
-      Thread.sleep(250);
-      
-      List msgs = receiver.getMessages();
-      
-      assertNotNull(msgs);
-      
-      assertEquals(1, msgs.size());
-      
-      Message msgRec = (Message)msgs.get(0);
-      
-      assertTrue(msg == msgRec);  
-      
-      receiver.clear();
-   }
-   
-
-   // Private -------------------------------------------------------
-   
-   
-   // Inner classes -------------------------------------------------
-   
-   class SimpleQueue implements ClusteredQueue
-   {
-      private boolean local;
-      
-      private Receiver receiver;
-      
-      private List refs = new ArrayList();
-        
-      SimpleQueue(boolean local)
-      {
-         this.local = local;
-      }
-
-      public int getNodeId()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public QueueStats getStats()
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public boolean isLocal()
-      {
-         return local;
-      }
-
-      public Filter getFilter()
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public String getName()
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public boolean isClustered()
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public boolean acceptReliableMessages()
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public void activate()
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public List browse()
-      {
-         List msgs = new ArrayList();
-         
-         Iterator iter = refs.iterator();
-         
-         while (iter.hasNext())
-         {
-            MessageReference ref = (MessageReference)iter.next();
-            
-            msgs.add(ref);
-         }
-         
-         return msgs;
-      }
-
-      public List browse(Filter filter)
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public void clear()
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public void close()
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public void deactivate()
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public void deliver()
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public List delivering(Filter filter)
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public long getChannelID()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public boolean isActive()
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public boolean isRecoverable()
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public void load() throws Exception
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public int getMessageCount()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public void removeAllReferences() throws Throwable
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public List undelivered(Filter filter)
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public void unload() throws Exception
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public Delivery handle(DeliveryObserver observer, MessageReference reference, Transaction tx)
-      {
-         if (receiver != null)
-         {
-            // Send to receiver
-            return receiver.handle(observer, reference, tx);
-         }
-         else
-         {
-            // Store internally
-            refs.add(reference);
-            
-            return new SimpleDelivery(observer, reference);
-         }
-         
-      
-      }
-
-      public void acknowledge(Delivery d, Transaction tx) throws Throwable
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public void cancel(Delivery d) throws Throwable
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public boolean add(Receiver receiver)
-      {
-         this.receiver = receiver;
-         
-         return true;
-      }
-
-      public boolean contains(Receiver receiver)
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public Iterator iterator()
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public int getNumberOfReceivers()
-      {
-         if (receiver != null)
-         {
-            return 1;
-         }
-         else
-         {
-            return 0;
-         }
-      }
-
-      public boolean remove(Receiver receiver)
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public List recoverDeliveries(List messageIds)
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public void addDelivery(Delivery del)
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public int getDeliveringCount()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public int getMaxSize()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public int getMessagesAdded()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public void setMaxSize(int newSize)
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public int getScheduledCount()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      
-   }
-   
-
-}
-
-
-

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/FailoverMapperTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/FailoverMapperTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/FailoverMapperTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,61 +0,0 @@
-/*
-   * JBoss, Home of Professional Open Source
-   * Copyright 2005, JBoss Inc., and individual contributors as indicated
-   * by the @authors tag. See the copyright.txt in the distribution for a
-   * full listing of individual contributors.
-   *
-   * This is free software; you can redistribute it and/or modify it
-   * under the terms of the GNU Lesser General Public License as
-   * published by the Free Software Foundation; either version 2.1 of
-   * the License, or (at your option) any later version.
-   *
-   * This software is distributed in the hope that it will be useful,
-   * but WITHOUT ANY WARRANTY; without even the implied warranty of
-   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   * Lesser General Public License for more details.
-   *
-   * You should have received a copy of the GNU Lesser General Public
-   * License along with this software; if not, write to the Free
-   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-   */
-
-package org.jboss.test.messaging.core.plugin.postoffice.cluster;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import junit.framework.TestCase;
-
-import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultFailoverMapper;
-
-/**
- * @author <a href="mailto:clebert.suconic at jboss.org">Clebert Suconic</a>
- * @version <tt>$Revision:$</tt>
- *          <p/>
- *          $Id:$
- */
-public class FailoverMapperTest extends TestCase
-{
-
-   public void testMapper()
-   {
-      Set set = new HashSet();
-
-      set.add(new Integer(50));
-      set.add(new Integer(25));
-      set.add(new Integer(15));
-
-      DefaultFailoverMapper mapper = new DefaultFailoverMapper();
-      Map map = mapper.generateMapping(set);
-
-      assertEquals(new Integer(25), map.get(new Integer(15)));
-      assertEquals(new Integer(50), map.get(new Integer(25)));
-      assertEquals(new Integer(15), map.get(new Integer(50)));
-      
-      
-   }
-
-
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RecoveryTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RecoveryTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RecoveryTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,349 +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.postoffice.cluster;
-
-import java.util.List;
-
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
-import org.jboss.messaging.core.plugin.postoffice.cluster.LocalClusteredQueue;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.messaging.core.tx.TransactionException;
-import org.jboss.test.messaging.core.SimpleCondition;
-import org.jboss.test.messaging.core.SimpleReceiver;
-import org.jboss.test.messaging.core.plugin.base.PostOfficeTestBase;
-import org.jboss.test.messaging.util.CoreMessageFactory;
-
-/**
- * A RecoveryTest
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- * 
- * $Id$
- */
-public class RecoveryTest extends PostOfficeTestBase
-{
-   // Constants ------------------------------------------------------------------------------------
-
-   // Static ---------------------------------------------------------------------------------------
-
-   // Attributes -----------------------------------------------------------------------------------
-
-   // Constructors ---------------------------------------------------------------------------------
-
-   public RecoveryTest(String name)
-   {
-      super(name);
-   }
-
-   // Public ---------------------------------------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-   }
-
-   public void tearDown() throws Exception
-   {
-      super.tearDown();
-   }
-
-   public void testCrashBeforePersist() throws Exception
-   {
-      DefaultClusteredPostOffice office1 = null;
-      DefaultClusteredPostOffice office2 = null;
-      DefaultClusteredPostOffice office3 = null;
-
-      try
-      {
-         office1 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(1, "testgroup", sc, ms, pm, tr);
-         office2 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(2, "testgroup", sc, ms, pm, tr);
-         office3 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(3, "testgroup", sc, ms, pm, tr);
-
-         LocalClusteredQueue queue1 =
-            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-         office1.bindClusteredQueue(new SimpleCondition("topic1"), queue1);
-
-         LocalClusteredQueue queue2 =
-            new LocalClusteredQueue(office2, 2, "queue2", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-            office2.bindClusteredQueue(new SimpleCondition("topic1"), queue2);
-
-         LocalClusteredQueue queue3 =
-            new LocalClusteredQueue(office3, 3, "queue3", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-            office3.bindClusteredQueue(new SimpleCondition("topic1"), queue3);
-
-         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue1.add(receiver1);
-         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue2.add(receiver2);
-         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue3.add(receiver3);
-
-         //This will make it fail after casting but before persisting the message in the db
-         office1.setFail(true, false, false);
-
-         Transaction tx = tr.createTransaction();
-
-         final int NUM_MESSAGES = 10;
-
-         for (int i = 0; i < NUM_MESSAGES; i++)
-         {
-            Message msg = CoreMessageFactory.createCoreMessage(i, true, null);
-
-            MessageReference ref = ms.reference(msg);
-
-            office1.route(ref, new SimpleCondition("topic1"), tx);
-         }
-
-         Thread.sleep(1000);
-
-         List msgs = receiver1.getMessages();
-         assertTrue(msgs.isEmpty());
-
-         msgs = receiver2.getMessages();
-         assertTrue(msgs.isEmpty());
-
-         msgs = receiver3.getMessages();
-         assertTrue(msgs.isEmpty());
-
-         try
-         {
-            //An exception should be thrown            
-            tx.commit();
-            fail();
-         }
-         catch (TransactionException e)
-         {
-            //Ok
-         }
-
-         Thread.sleep(1000);
-
-         msgs = receiver1.getMessages();
-         assertTrue(msgs.isEmpty());
-
-         msgs = receiver2.getMessages();
-         assertTrue(msgs.isEmpty());
-
-         msgs = receiver3.getMessages();
-         assertTrue(msgs.isEmpty());
-
-         //Nodes 2 and 3 should have a held tx
-
-         assertTrue(office1.getHoldingTransactions().isEmpty());
-
-         assertEquals(1, office2.getHoldingTransactions().size());
-
-         assertEquals(1, office3.getHoldingTransactions().size());
-
-         //We now kill the office - this should make the other offices do their transaction check
-         office1.stop();
-
-         Thread.sleep(1000);
-
-         //This should result in the held txs being rolled back
-
-         assertTrue(office1.getHoldingTransactions().isEmpty());
-
-         assertTrue(office2.getHoldingTransactions().isEmpty());
-
-         assertTrue(office3.getHoldingTransactions().isEmpty());
-
-         //The tx should be removed from the holding area and nothing should be received
-         //remember node1 has now crashed so no point checking receiver1
-
-         msgs = receiver2.getMessages();
-         assertTrue(msgs.isEmpty());
-
-         msgs = receiver3.getMessages();
-         assertTrue(msgs.isEmpty());
-
-      }
-      finally
-      {
-         if (office1 != null)
-         {
-            office1.stop();
-         }
-
-         if (office2 != null)
-         {
-            office2.stop();
-         }
-
-         if (office3 != null)
-         {
-            office3.stop();
-         }
-      }
-   }
-
-   public void testCrashAfterPersist() throws Exception
-   {
-      DefaultClusteredPostOffice office1 = null;
-      DefaultClusteredPostOffice office2 = null;
-      DefaultClusteredPostOffice office3 = null;
-
-      try
-      {
-         office1 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(1, "testgroup", sc, ms, pm, tr);
-
-         office2 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(2, "testgroup", sc, ms, pm, tr);
-
-         office3 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(3, "testgroup", sc, ms, pm, tr);
-
-         LocalClusteredQueue queue1 =
-            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-         office1.bindClusteredQueue(new SimpleCondition("topic1"), queue1);
-
-         LocalClusteredQueue queue2 =
-            new LocalClusteredQueue(office2, 2, "queue2", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-         office2.bindClusteredQueue(new SimpleCondition("topic1"), queue2);
-
-         LocalClusteredQueue queue3 =
-            new LocalClusteredQueue(office3, 3, "queue3", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-         office3.bindClusteredQueue(new SimpleCondition("topic1"), queue3);
-
-         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue1.add(receiver1);
-         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue2.add(receiver2);
-         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-         queue3.add(receiver3);
-
-         //This will make it fail after casting and persisting the message in the db
-         office1.setFail(false, true, false);
-
-         Transaction tx = tr.createTransaction();
-
-         final int NUM_MESSAGES = 10;
-
-         for (int i = 0; i < NUM_MESSAGES; i++)
-         {
-            Message msg = CoreMessageFactory.createCoreMessage(i, true, null);
-
-            MessageReference ref = ms.reference(msg);
-
-            office1.route(ref, new SimpleCondition("topic1"), tx);
-         }
-
-         Thread.sleep(1000);
-
-         List msgs = receiver1.getMessages();
-         assertTrue(msgs.isEmpty());
-
-         msgs = receiver2.getMessages();
-         assertTrue(msgs.isEmpty());
-
-         msgs = receiver3.getMessages();
-         assertTrue(msgs.isEmpty());
-
-         try
-         {
-            //An exception should be thrown            
-            tx.commit();
-            fail();
-         }
-         catch (TransactionException e)
-         {
-            //Ok
-         }
-
-         Thread.sleep(1000);
-
-         msgs = receiver1.getMessages();
-         assertTrue(msgs.isEmpty());
-
-         msgs = receiver2.getMessages();
-         assertTrue(msgs.isEmpty());
-
-         msgs = receiver3.getMessages();
-         assertTrue(msgs.isEmpty());
-
-         //There should be held tx in 2 and 3 but not in 1
-
-         assertTrue(office1.getHoldingTransactions().isEmpty());
-
-         assertEquals(1, office2.getHoldingTransactions().size());
-
-         assertEquals(1, office3.getHoldingTransactions().size());
-
-         //We now kill the office - this should make the other office do it's transaction check
-         office1.stop();
-
-         Thread.sleep(1000);
-
-         assertTrue(office1.getHoldingTransactions().isEmpty());
-
-         assertTrue(office2.getHoldingTransactions().isEmpty());
-
-         assertTrue(office3.getHoldingTransactions().isEmpty());
-
-         //The tx should be removed from the holding area and messages be received
-         //no point checking receiver1 since node1 has crashed
-
-         msgs = receiver2.getMessages();
-         assertEquals(NUM_MESSAGES, msgs.size());
-
-         msgs = receiver3.getMessages();
-         assertEquals(NUM_MESSAGES, msgs.size());
-
-
-      }
-      finally
-      {
-         if (office1 != null)
-         {
-            office1.stop();
-         }
-
-         if (office2 != null)
-         {
-            office2.stop();
-         }
-      }
-   }
-
-
-   // Private --------------------------------------------------------------------------------------
-
-   // Inner classes --------------------------------------------------------------------------------
-
-}
-
-
-
-

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RedistributionWithDefaultMessagePullPolicyTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RedistributionWithDefaultMessagePullPolicyTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RedistributionWithDefaultMessagePullPolicyTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,1260 +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.postoffice.cluster;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.jboss.messaging.core.Channel;
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.DeliveryObserver;
-import org.jboss.messaging.core.Receiver;
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
-import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultMessagePullPolicy;
-import org.jboss.messaging.core.plugin.postoffice.cluster.LocalClusteredQueue;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.test.messaging.core.SimpleCondition;
-import org.jboss.test.messaging.core.SimpleReceiver;
-import org.jboss.test.messaging.core.plugin.base.PostOfficeTestBase;
-import org.jboss.test.messaging.util.CoreMessageFactory;
-
-import EDU.oswego.cs.dl.util.concurrent.Executor;
-import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
-
-/**
- * A RedistributionWithDefaultMessagePullPolicyTest
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @author <a href="mailto:ovidiu at jboss.org">Oviidu Feodorov</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class RedistributionWithDefaultMessagePullPolicyTest extends PostOfficeTestBase
-{
-   // Constants ------------------------------------------------------------------------------------
-
-   // Static ---------------------------------------------------------------------------------------
-
-   // Attributes -----------------------------------------------------------------------------------
-
-   // Constructors ---------------------------------------------------------------------------------
-
-   public RedistributionWithDefaultMessagePullPolicyTest(String name)
-   {
-      super(name);
-   }
-
-   // Public ---------------------------------------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-   }
-
-   public void tearDown() throws Exception
-   {
-      super.tearDown();
-   }
-
-   public void testConsumeAllNonPersistentNonRecoverable() throws Throwable
-   {
-      consumeAll(false, false);
-   }
-
-   public void testConsumeAllPersistentNonRecoverable() throws Throwable
-   {
-      consumeAll(true, false);
-   }
-
-   public void testConsumeAllNonPersistentRecoverable() throws Throwable
-   {
-      consumeAll(false, true);
-   }
-
-   public void testConsumeAllPersistentRecoverable() throws Throwable
-   {
-      consumeAll(true, true);
-   }
-
-// Commented because of http://jira.jboss.com/jira/browse/JBMESSAGING-972 
-//   public void testConsumeBitByBitNonPersistentNonRecoverable() throws Throwable
-//   {
-//      consumeBitByBit(false, false);
-//   }
-//
-//   public void testConsumeBitByBitPersistentNonRecoverable() throws Throwable
-//   {
-//      consumeBitByBit(true, false);
-//   }
-//
-//   public void testConsumeBitByBitNonPersistentRecoverable() throws Throwable
-//   {
-//      consumeBitByBit(false, true);
-//   }
-//
-//   public void testConsumeBitByBitPersistentRecoverable() throws Throwable
-//   {
-//      consumeBitByBit(true, true);
-//   }
-
-   public void testSimpleMessagePull() throws Throwable
-   {
-      DefaultClusteredPostOffice office1 = null;
-      DefaultClusteredPostOffice office2 = null;
-
-      try
-      {
-         office1 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(1, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-                                      sc, ms, pm, tr);
-
-         office2 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(2, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-                                      sc, ms, pm, tr);
-
-         LocalClusteredQueue queue1 =
-            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-
-         office1.bindClusteredQueue(new SimpleCondition("queue1"), queue1);
-
-         LocalClusteredQueue queue2 =
-            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, true, -1, null, tr);
-         office2.bindClusteredQueue(new SimpleCondition("queue1"), queue2);
-
-         Message msg = CoreMessageFactory.createCoreMessage(1, true, null);
-
-         MessageReference ref = ms.reference(msg);
-
-         office1.route(ref, new SimpleCondition("queue1"), null);
-
-         Thread.sleep(2000);
-
-         // Messages should all be in queue1
-
-         List msgs = queue1.browse();
-         assertEquals(1, msgs.size());
-
-         msgs = queue2.browse();
-         assertTrue(msgs.isEmpty());
-
-         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
-         receiver1.setMaxRefs(0);
-         queue1.add(receiver1);
-         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
-         receiver2.setMaxRefs(0);
-         queue2.add(receiver2);
-
-         // Prompt delivery so the channels know if the receivers are ready
-         queue1.deliver();
-         Thread.sleep(2000);
-
-         // Pull from 1 to 2
-
-         receiver2.setMaxRefs(1);
-
-         log.trace("delivering");
-         queue2.deliver();
-
-         Thread.sleep(3000);
-
-         assertTrue(office1.getHoldingTransactions().isEmpty());
-         assertTrue(office2.getHoldingTransactions().isEmpty());
-
-         log.trace("r2 " + receiver2.getMessages().size());
-
-         log.trace("queue1 refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
-         log.trace("queue2 refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
-
-         assertEquals(0, queue1.memoryRefCount());
-         assertEquals(0, queue1.getDeliveringCount());
-
-         assertEquals(0, queue2.memoryRefCount());
-         assertEquals(1, queue2.getDeliveringCount());
-
-         this.acknowledgeAll(receiver2);
-
-         assertEquals(0, queue2.memoryRefCount());
-         assertEquals(0, queue2.getDeliveringCount());
-
-         assertTrue(office1.getHoldingTransactions().isEmpty());
-         assertTrue(office2.getHoldingTransactions().isEmpty());
-
-      }
-      finally
-      {
-         if (office1 != null)
-         {
-            office1.stop();
-         }
-
-         if (office2 != null)
-         {
-            office2.stop();
-         }
-      }
-   }
-
-// Commented because of http://jira.jboss.com/jira/browse/JBMESSAGING-972
-//   public void testSimpleMessagePullCrashBeforeCommit() throws Throwable
-//   {
-//      DefaultClusteredPostOffice office1 = null;
-//      DefaultClusteredPostOffice office2 = null;
-//
-//      try
-//      {
-//         office1 = (DefaultClusteredPostOffice)
-//            createClusteredPostOffice(1, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-//                                      sc, ms, pm, tr);
-//
-//         office2 = (DefaultClusteredPostOffice)
-//            createClusteredPostOffice(2, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-//                                      sc, ms, pm, tr);
-//
-//         LocalClusteredQueue queue1 =
-//            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
-//                                    true, true, -1, null, tr);
-//         office1.bindClusteredQueue(new SimpleCondition("queue1"), queue1);
-//
-//         LocalClusteredQueue queue2 =
-//            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
-//                                    true, true, -1, null, tr);
-//         office2.bindClusteredQueue(new SimpleCondition("queue1"), queue2);
-//
-//         Message msg = CoreMessageFactory.createCoreMessage(1, true, null);
-//
-//         MessageReference ref = ms.reference(msg);
-//
-//         office1.route(ref, new SimpleCondition("queue1"), null);
-//
-//         Thread.sleep(2000);
-//
-//         //Messages should all be in queue1
-//
-//         List msgs = queue1.browse();
-//         assertEquals(1, msgs.size());
-//
-//         msgs = queue2.browse();
-//         assertTrue(msgs.isEmpty());
-//
-//         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
-//         receiver1.setMaxRefs(0);
-//         queue1.add(receiver1);
-//         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
-//         receiver2.setMaxRefs(0);
-//         queue2.add(receiver2);
-//
-//         //Prompt delivery so the channels know if the receivers are ready
-//         queue1.deliver();
-//         Thread.sleep(2000);
-//
-//         //Pull from 1 to 2
-//
-//         receiver2.setMaxRefs(1);
-//
-//         //Force a failure before commit
-//         office2.setFail(true, false, false);
-//
-//         log.trace("delivering");
-//         queue2.deliver();
-//
-//         Thread.sleep(3000);
-//
-//         assertEquals(1, office1.getHoldingTransactions().size());
-//         assertTrue(office2.getHoldingTransactions().isEmpty());
-//
-//         log.trace("queue1 refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
-//         log.trace("queue2 refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
-//
-//         assertEquals(0, queue1.memoryRefCount());
-//         assertEquals(1, queue1.getDeliveringCount());
-//
-//         assertEquals(0, queue2.memoryRefCount());
-//         assertEquals(0, queue2.getDeliveringCount());
-//
-//         //Now kill office 2 - this should cause office1 to remove the dead held transaction
-//
-//         office2.stop();
-//         Thread.sleep(2000);
-//
-//         assertTrue(office1.getHoldingTransactions().isEmpty());
-//
-//         //The delivery should be cancelled back to the queue too
-//
-//         assertEquals(1, queue1.memoryRefCount());
-//         assertEquals(0, queue1.getDeliveringCount());
-//
-//
-//      }
-//      finally
-//      {
-//         if (office1 != null)
-//         {
-//            office1.stop();
-//         }
-//
-//         if (office2 != null)
-//         {
-//            office2.stop();
-//         }
-//      }
-//   }
-//
-   
-// Commented because of http://jira.jboss.com/jira/browse/JBMESSAGING-972   
-//   public void testSimpleMessagePullCrashAfterCommit() throws Throwable
-//   {
-//      DefaultClusteredPostOffice office1 = null;
-//      DefaultClusteredPostOffice office2 = null;
-//
-//      try
-//      {
-//         office1 = (DefaultClusteredPostOffice)
-//            createClusteredPostOffice(1, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-//                                      sc, ms, pm, tr);
-//
-//         office2 = (DefaultClusteredPostOffice)
-//            createClusteredPostOffice(2, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-//                                      sc, ms, pm, tr);
-//
-//         LocalClusteredQueue queue1 =
-//            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
-//                                    true, true, -1, null, tr);
-//         office1.bindClusteredQueue(new SimpleCondition("queue1"), queue1);
-//
-//         LocalClusteredQueue queue2 =
-//            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
-//                                    true, true, -1, null, tr);
-//         office2.bindClusteredQueue(new SimpleCondition("queue1"), queue2);
-//
-//         Message msg = CoreMessageFactory.createCoreMessage(1, true, null);
-//
-//         MessageReference ref = ms.reference(msg);
-//
-//         office1.route(ref, new SimpleCondition("queue1"), null);
-//
-//         Thread.sleep(2000);
-//
-//         //Messages should all be in queue1
-//
-//         List msgs = queue1.browse();
-//         assertEquals(1, msgs.size());
-//
-//         msgs = queue2.browse();
-//         assertTrue(msgs.isEmpty());
-//
-//         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
-//         receiver1.setMaxRefs(0);
-//         queue1.add(receiver1);
-//         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
-//         receiver2.setMaxRefs(0);
-//         queue2.add(receiver2);
-//
-//         //Prompt delivery so the channels know if the receivers are ready
-//         queue1.deliver();
-//         Thread.sleep(2000);
-//
-//         //Pull from 1 to 2
-//
-//         receiver2.setMaxRefs(1);
-//
-//         //Force a failure after commit the ack to storage
-//         office2.setFail(false, true, false);
-//
-//         log.trace("delivering");
-//         queue2.deliver();
-//
-//         Thread.sleep(3000);
-//
-//         assertEquals(1, office1.getHoldingTransactions().size());
-//         assertTrue(office2.getHoldingTransactions().isEmpty());
-//
-//         log.trace("queue1 refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
-//         log.trace("queue2 refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
-//
-//         assertEquals(0, queue1.memoryRefCount());
-//         assertEquals(1, queue1.getDeliveringCount());
-//
-//         //Now kill office 2 - this should cause office1 to remove the dead held transaction
-//
-//         office2.stop();
-//         Thread.sleep(2000);
-//
-//         assertTrue(office1.getHoldingTransactions().isEmpty());
-//
-//         //The delivery should be committed
-//
-//         assertEquals(0, queue1.memoryRefCount());
-//         assertEquals(0, queue1.getDeliveringCount());
-//
-//      }
-//      finally
-//      {
-//         if (office1 != null)
-//         {
-//            office1.stop();
-//         }
-//
-//         if (office2 != null)
-//         {
-//            office2.stop();
-//         }
-//      }
-//   }
-
-// Commented because of http://jira.jboss.com/jira/browse/JBMESSAGING-972    
-//   public void testFailHandleMessagePullResult() throws Throwable
-//   {
-//      DefaultClusteredPostOffice office1 = null;
-//      DefaultClusteredPostOffice office2 = null;
-//
-//      try
-//      {
-//         office1 = (DefaultClusteredPostOffice)
-//            createClusteredPostOffice(1, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-//                                      sc, ms, pm, tr);
-//
-//         office2 = (DefaultClusteredPostOffice)
-//            createClusteredPostOffice(2, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-//                                      sc, ms, pm, tr);
-//
-//         LocalClusteredQueue queue1 =
-//            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
-//                                    true, true, -1, null, tr);
-//         office1.bindClusteredQueue(new SimpleCondition("queue1"), queue1);
-//
-//         LocalClusteredQueue queue2 =
-//            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
-//                                    true, true, -1, null, tr);
-//         office2.bindClusteredQueue(new SimpleCondition("queue1"), queue2);
-//
-//         Message msg = CoreMessageFactory.createCoreMessage(1, true, null);
-//
-//         MessageReference ref = ms.reference(msg);
-//
-//         office1.route(ref, new SimpleCondition("queue1"), null);
-//
-//         Thread.sleep(2000);
-//
-//         //Messages should all be in queue1
-//
-//         List msgs = queue1.browse();
-//         assertEquals(1, msgs.size());
-//
-//         msgs = queue2.browse();
-//         assertTrue(msgs.isEmpty());
-//
-//         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
-//         receiver1.setMaxRefs(0);
-//         queue1.add(receiver1);
-//         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
-//         receiver2.setMaxRefs(0);
-//         queue2.add(receiver2);
-//
-//         //Prompt delivery so the channels know if the receivers are ready
-//         queue1.deliver();
-//         Thread.sleep(2000);
-//
-//         //Pull from 1 to 2
-//
-//         receiver2.setMaxRefs(1);
-//
-//         office2.setFail(false, false, true);
-//
-//         log.trace("delivering");
-//         queue2.deliver();
-//
-//         Thread.sleep(3000);
-//
-//         //The delivery should be rolled back
-//
-//         assertTrue(office2.getHoldingTransactions().isEmpty());
-//         assertTrue(office2.getHoldingTransactions().isEmpty());
-//
-//         log.trace("queue1 refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
-//         log.trace("queue2 refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
-//
-//         assertEquals(1, queue1.memoryRefCount());
-//         assertEquals(0, queue1.getDeliveringCount());
-//
-//         assertEquals(0, queue2.memoryRefCount());
-//         assertEquals(0, queue2.getDeliveringCount());
-//      }
-//      finally
-//      {
-//         if (office1 != null)
-//         {
-//            office1.stop();
-//         }
-//
-//         if (office2 != null)
-//         {
-//            office2.stop();
-//         }
-//      }
-//   }
-
-   protected void consumeAll(boolean persistent, boolean recoverable) throws Throwable
-   {
-      DefaultClusteredPostOffice office1 = null;
-      DefaultClusteredPostOffice office2 = null;
-      DefaultClusteredPostOffice office3 = null;
-      DefaultClusteredPostOffice office4 = null;
-      DefaultClusteredPostOffice office5 = null;
-
-      boolean readOK;
-
-      try
-      {
-         log.trace("Creating post offices");
-
-         office1 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(1, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-                                      sc, ms, pm, tr);
-
-         office2 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(2, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-                                      sc, ms, pm, tr);
-
-         office3 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(3, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-                                      sc, ms, pm, tr);
-
-         office4 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(4, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-                                      sc, ms, pm, tr);
-
-         office5 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(5, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-                                      sc, ms, pm, tr);
-
-         log.trace("Created postoffices");
-
-         LocalClusteredQueue queue1 =
-            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, recoverable, -1, null, tr);
-         office1.bindClusteredQueue(new SimpleCondition("queue1"), queue1);
-
-         LocalClusteredQueue queue2 =
-            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, recoverable, -1, null, tr);
-         office2.bindClusteredQueue(new SimpleCondition("queue1"), queue2);
-
-         LocalClusteredQueue queue3 =
-            new LocalClusteredQueue(office3, 3, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, recoverable, -1, null, tr);
-         office3.bindClusteredQueue(new SimpleCondition("queue1"), queue3);
-
-         LocalClusteredQueue queue4 =
-            new LocalClusteredQueue(office4, 4, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, recoverable, -1, null, tr);
-         office4.bindClusteredQueue(new SimpleCondition("queue1"), queue4);
-
-         LocalClusteredQueue queue5 =
-            new LocalClusteredQueue(office5, 5, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, recoverable, -1, null, tr);
-         office5.bindClusteredQueue(new SimpleCondition("queue1"), queue5);
-
-         log.trace("Created and bound queues");
-
-         final int NUM_MESSAGES = 100;
-
-         log.trace("sending messages");
-         this.sendMessages("queue1", persistent, office1, NUM_MESSAGES, null);
-         this.sendMessages("queue1", persistent, office2, NUM_MESSAGES, null);
-         this.sendMessages("queue1", persistent, office3, NUM_MESSAGES, null);
-         this.sendMessages("queue1", persistent, office4, NUM_MESSAGES, null);
-         this.sendMessages("queue1", persistent, office5, NUM_MESSAGES, null);
-
-         log.trace("sent messages");
-
-         Thread.sleep(2000);
-
-
-         log.trace("Finished small sleep");
-
-         //Check the sizes
-
-         log.trace("Here are the sizes:");
-         log.trace("queue1, refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
-         log.trace("queue2, refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
-         log.trace("queue3, refs:" + queue3.memoryRefCount() + " dels:" + queue3.getDeliveringCount());
-         log.trace("queue4, refs:" + queue4.memoryRefCount() + " dels:" + queue4.getDeliveringCount());
-         log.trace("queue5, refs:" + queue5.memoryRefCount() + " dels:" + queue5.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES, queue1.memoryRefCount());
-         assertEquals(0, queue1.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES, queue2.memoryRefCount());
-         assertEquals(0, queue2.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES, queue3.memoryRefCount());
-         assertEquals(0, queue3.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES, queue4.memoryRefCount());
-         assertEquals(0, queue4.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES, queue5.memoryRefCount());
-         assertEquals(0, queue5.getDeliveringCount());
-
-         log.trace("Creating receiver");
-
-         SimpleReceiver receiver = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-
-         log.trace("Created receiver");
-
-         queue1.add(receiver);
-
-         log.trace("Added receiver");
-
-         queue1.deliver();
-
-         log.trace("Called deliver");
-
-         log.trace("Waiting for handleInvocations");
-         long start = System.currentTimeMillis();
-         readOK = receiver.waitForHandleInvocations(NUM_MESSAGES * 5, 60000);
-         long end = System.currentTimeMillis();
-         log.trace("I waited for " + (end - start) + " ms");
-
-         assertTrue(readOK);
-
-         Thread.sleep(2000);
-
-
-         log.trace("Here are the sizes:");
-         log.trace("queue1, refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
-         log.trace("queue2, refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
-         log.trace("queue3, refs:" + queue3.memoryRefCount() + " dels:" + queue3.getDeliveringCount());
-         log.trace("queue4, refs:" + queue4.memoryRefCount() + " dels:" + queue4.getDeliveringCount());
-         log.trace("queue5, refs:" + queue5.memoryRefCount() + " dels:" + queue5.getDeliveringCount());
-
-         assertEquals(0, queue1.memoryRefCount());
-         assertEquals(NUM_MESSAGES * 5, queue1.getDeliveringCount());
-
-         assertEquals(0, queue2.memoryRefCount());
-         assertEquals(0, queue2.getDeliveringCount());
-
-         assertEquals(0, queue3.memoryRefCount());
-         assertEquals(0, queue3.getDeliveringCount());
-
-         assertEquals(0, queue4.memoryRefCount());
-         assertEquals(0, queue4.getDeliveringCount());
-
-         assertEquals(0, queue5.memoryRefCount());
-         assertEquals(0, queue5.getDeliveringCount());
-
-         List messages = receiver.getMessages();
-
-         assertNotNull(messages);
-
-         assertEquals(NUM_MESSAGES * 5, messages.size());
-
-         Iterator iter = messages.iterator();
-
-         log.trace("Acknowledging messages");
-
-         while (iter.hasNext())
-         {
-            Message msg = (Message) iter.next();
-
-            receiver.acknowledge(msg, null);
-         }
-
-         log.trace("Acknowledged messages");
-
-         receiver.clear();
-
-         assertEquals(0, queue1.memoryRefCount());
-         assertEquals(0, queue1.getDeliveringCount());
-
-         assertTrue(office1.getHoldingTransactions().isEmpty());
-         assertTrue(office2.getHoldingTransactions().isEmpty());
-         assertTrue(office3.getHoldingTransactions().isEmpty());
-         assertTrue(office4.getHoldingTransactions().isEmpty());
-         assertTrue(office5.getHoldingTransactions().isEmpty());
-
-         if (checkNoMessageData())
-         {
-            fail("Message data still in database");
-         }
-      }
-      finally
-      {
-         if (office1 != null)
-         {
-            office1.stop();
-         }
-
-         if (office2 != null)
-         {
-            office2.stop();
-         }
-
-         if (office3 != null)
-         {
-            office3.stop();
-         }
-
-         if (office4 != null)
-         {
-            office4.stop();
-         }
-
-         if (office5 != null)
-         {
-            office5.stop();
-         }
-      }
-   }
-
-   protected void consumeBitByBit(boolean persistent, boolean recoverable) throws Throwable
-   {
-      DefaultClusteredPostOffice office1 = null;
-      DefaultClusteredPostOffice office2 = null;
-      DefaultClusteredPostOffice office3 = null;
-      DefaultClusteredPostOffice office4 = null;
-      DefaultClusteredPostOffice office5 = null;
-
-      boolean readOK;
-
-      try
-      {
-         office1 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(1, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-                                      sc, ms, pm, tr);
-
-         office2 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(2, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-                                      sc, ms, pm, tr);
-
-         office3 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(3, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-                                      sc, ms, pm, tr);
-
-         office4 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(4, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-                                      sc, ms, pm, tr);
-
-         office5 = (DefaultClusteredPostOffice)
-            createClusteredPostOffice(5, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
-                                      sc, ms, pm, tr);
-
-         LocalClusteredQueue queue1 =
-            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, recoverable, -1, null, tr);
-         office1.bindClusteredQueue(new SimpleCondition("queue1"), queue1);
-
-         LocalClusteredQueue queue2 =
-            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, recoverable, -1, null, tr);
-         office2.bindClusteredQueue(new SimpleCondition("queue1"), queue2);
-
-         LocalClusteredQueue queue3 =
-            new LocalClusteredQueue(office3, 3, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, recoverable, -1, null, tr);
-         office3.bindClusteredQueue(new SimpleCondition("queue1"), queue3);
-
-         LocalClusteredQueue queue4 =
-            new LocalClusteredQueue(office4, 4, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, recoverable, -1, null, tr);
-         office4.bindClusteredQueue(new SimpleCondition("queue1"), queue4);
-
-         LocalClusteredQueue queue5 =
-            new LocalClusteredQueue(office5, 5, "queue1", channelIDManager.getID(), ms, pm,
-                                    true, recoverable, -1, null, tr);
-         office5.bindClusteredQueue(new SimpleCondition("queue1"), queue5);
-
-         final int NUM_MESSAGES = 100;
-
-         this.sendMessages("queue1", persistent, office1, NUM_MESSAGES, null);
-         this.sendMessages("queue1", persistent, office2, NUM_MESSAGES, null);
-         this.sendMessages("queue1", persistent, office3, NUM_MESSAGES, null);
-         this.sendMessages("queue1", persistent, office4, NUM_MESSAGES, null);
-         this.sendMessages("queue1", persistent, office5, NUM_MESSAGES, null);
-
-         Thread.sleep(2000);
-
-         // Check the sizes
-
-         log.trace("Here are the sizes 1:");
-         log.trace("queue1, refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
-         log.trace("queue2, refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
-         log.trace("queue3, refs:" + queue3.memoryRefCount() + " dels:" + queue3.getDeliveringCount());
-         log.trace("queue4, refs:" + queue4.memoryRefCount() + " dels:" + queue4.getDeliveringCount());
-         log.trace("queue5, refs:" + queue5.memoryRefCount() + " dels:" + queue5.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES, queue1.memoryRefCount());
-         assertEquals(0, queue1.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES, queue2.memoryRefCount());
-         assertEquals(0, queue2.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES, queue3.memoryRefCount());
-         assertEquals(0, queue3.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES, queue4.memoryRefCount());
-         assertEquals(0, queue4.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES, queue5.memoryRefCount());
-         assertEquals(0, queue5.getDeliveringCount());
-
-         assertTrue(office1.getHoldingTransactions().isEmpty());
-         assertTrue(office2.getHoldingTransactions().isEmpty());
-         assertTrue(office3.getHoldingTransactions().isEmpty());
-         assertTrue(office4.getHoldingTransactions().isEmpty());
-         assertTrue(office5.getHoldingTransactions().isEmpty());
-
-         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
-         queue1.add(receiver1);
-         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
-         queue2.add(receiver2);
-         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
-         queue3.add(receiver3);
-         SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
-         queue4.add(receiver4);
-         SimpleReceiver receiver5 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
-         queue5.add(receiver5);
-
-         receiver1.setMaxRefs(5);
-         queue1.deliver();
-         readOK = receiver1.waitForHandleInvocations(5, 20000);
-         assertTrue(readOK);
-         Thread.sleep(1000);
-         assertEquals(NUM_MESSAGES - 5, queue1.memoryRefCount());
-         assertEquals(5, queue1.getDeliveringCount());
-
-         acknowledgeAll(receiver1);
-         assertEquals(0, queue1.getDeliveringCount());
-         receiver1.setMaxRefs(0);
-
-         receiver2.setMaxRefs(10);
-         queue2.deliver();
-         readOK = receiver2.waitForHandleInvocations(10, 20000);
-         assertTrue(readOK);
-         Thread.sleep(1000);
-         assertEquals(NUM_MESSAGES - 10, queue2.memoryRefCount());
-         assertEquals(10, queue2.getDeliveringCount());
-         acknowledgeAll(receiver2);
-         receiver2.setMaxRefs(0);
-
-         receiver3.setMaxRefs(15);
-         queue3.deliver();
-         readOK = receiver3.waitForHandleInvocations(15, 20000);
-         Thread.sleep(1000);
-         assertEquals(NUM_MESSAGES - 15, queue3.memoryRefCount());
-         assertEquals(15, queue3.getDeliveringCount());
-         acknowledgeAll(receiver3);
-         receiver3.setMaxRefs(0);
-
-         receiver4.setMaxRefs(20);
-         queue4.deliver();
-         readOK = receiver4.waitForHandleInvocations(20, 20000);
-         assertTrue(readOK);
-         Thread.sleep(1000);
-         assertEquals(NUM_MESSAGES - 20, queue4.memoryRefCount());
-         assertEquals(20, queue4.getDeliveringCount());
-         acknowledgeAll(receiver4);
-         receiver4.setMaxRefs(0);
-
-         receiver5.setMaxRefs(25);
-         queue5.deliver();
-         readOK = receiver5.waitForHandleInvocations(25, 20000);
-         assertTrue(readOK);
-         Thread.sleep(1000);
-         assertEquals(NUM_MESSAGES - 25, queue5.memoryRefCount());
-         assertEquals(25, queue5.getDeliveringCount());
-         acknowledgeAll(receiver5);
-         receiver5.setMaxRefs(0);
-
-         assertTrue(office1.getHoldingTransactions().isEmpty());
-         assertTrue(office2.getHoldingTransactions().isEmpty());
-         assertTrue(office3.getHoldingTransactions().isEmpty());
-         assertTrue(office4.getHoldingTransactions().isEmpty());
-         assertTrue(office5.getHoldingTransactions().isEmpty());
-
-         log.trace("Here are the sizes 2:");
-         log.trace("queue1, refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
-         log.trace("queue2, refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
-         log.trace("queue3, refs:" + queue3.memoryRefCount() + " dels:" + queue3.getDeliveringCount());
-         log.trace("queue4, refs:" + queue4.memoryRefCount() + " dels:" + queue4.getDeliveringCount());
-         log.trace("queue5, refs:" + queue5.memoryRefCount() + " dels:" + queue5.getDeliveringCount());
-
-         // Consume the rest from queue 5
-         receiver5.setMaxRefs(NUM_MESSAGES - 25);
-         queue5.deliver();
-         readOK = receiver5.waitForHandleInvocations(NUM_MESSAGES - 25, 20000);
-         assertTrue(readOK);
-
-         Thread.sleep(2000);
-
-         log.trace("receiver5 msgs:" + receiver5.getMessages().size());
-
-         log.trace("Here are the sizes 3:");
-         log.trace("queue1, refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
-         log.trace("queue2, refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
-         log.trace("queue3, refs:" + queue3.memoryRefCount() + " dels:" + queue3.getDeliveringCount());
-         log.trace("queue4, refs:" + queue4.memoryRefCount() + " dels:" + queue4.getDeliveringCount());
-         log.trace("queue5, refs:" + queue5.memoryRefCount() + " dels:" + queue5.getDeliveringCount());
-
-         // This will result in an extra one being pulled from queue1 - we cannot avoid this. This
-         // is because the channel does not know that the receiver is full unless it tries with a
-         // ref so it needs to retrieve one
-
-                                                                   // http://jira.jboss.org/jira/browse/JBMESSAGING-901                                                                          
-         assertEquals(NUM_MESSAGES - 6, queue1.memoryRefCount());  // <-  expected:<94> but was:<93>
-         assertEquals(0, queue1.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES - 10, queue2.memoryRefCount());
-         assertEquals(0, queue2.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES - 15, queue3.memoryRefCount());
-         assertEquals(0, queue3.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES - 20, queue4.memoryRefCount());
-         assertEquals(0, queue4.getDeliveringCount());
-
-         assertEquals(1, queue5.memoryRefCount());
-         assertEquals(NUM_MESSAGES - 25, queue5.getDeliveringCount());
-
-         acknowledgeAll(receiver5);
-
-         assertEquals(0, queue5.getDeliveringCount());
-
-         receiver5.setMaxRefs(0);
-
-         assertTrue(office1.getHoldingTransactions().isEmpty());
-         assertTrue(office2.getHoldingTransactions().isEmpty());
-         assertTrue(office3.getHoldingTransactions().isEmpty());
-         assertTrue(office4.getHoldingTransactions().isEmpty());
-         assertTrue(office5.getHoldingTransactions().isEmpty());
-
-         // Now consume 5 more from queue5, they should come from queue1 which has the most messages
-
-         log.trace("Consume 5 more from queue 5");
-
-         receiver5.setMaxRefs(5);
-         queue5.deliver();
-         readOK = receiver5.waitForHandleInvocations(5, 20000);
-         assertTrue(readOK);
-
-         Thread.sleep(4000);
-
-         log.trace("Here are the sizes 4:");
-         log.trace("queue1, refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
-         log.trace("queue2, refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
-         log.trace("queue3, refs:" + queue3.memoryRefCount() + " dels:" + queue3.getDeliveringCount());
-         log.trace("queue4, refs:" + queue4.memoryRefCount() + " dels:" + queue4.getDeliveringCount());
-         log.trace("queue5, refs:" + queue5.memoryRefCount() + " dels:" + queue5.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES - 11, queue1.memoryRefCount()); // <--  expected:<89> but was:<88>
-
-         assertEquals(0, queue1.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES - 10, queue2.memoryRefCount());
-         assertEquals(0, queue2.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES - 15, queue3.memoryRefCount());
-         assertEquals(0, queue3.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES - 20, queue4.memoryRefCount());
-         assertEquals(0, queue4.getDeliveringCount());
-
-         assertEquals(1, queue5.memoryRefCount());
-         assertEquals(5, queue5.getDeliveringCount());
-
-         acknowledgeAll(receiver5);
-
-         assertEquals(0, queue5.getDeliveringCount());
-
-         receiver1.setMaxRefs(0);
-
-         assertTrue(office1.getHoldingTransactions().isEmpty());
-         assertTrue(office2.getHoldingTransactions().isEmpty());
-         assertTrue(office3.getHoldingTransactions().isEmpty());
-         assertTrue(office4.getHoldingTransactions().isEmpty());
-         assertTrue(office5.getHoldingTransactions().isEmpty());
-
-         // Consume 1 more - should pull one from queue2
-
-         receiver5.setMaxRefs(1);
-         queue5.deliver();
-         readOK = receiver5.waitForHandleInvocations(1, 20000);
-         assertTrue(readOK);
-
-         Thread.sleep(2000);
-
-         log.trace("Here are the sizes 5:");
-         log.trace("queue1, refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
-         log.trace("queue2, refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
-         log.trace("queue3, refs:" + queue3.memoryRefCount() + " dels:" + queue3.getDeliveringCount());
-         log.trace("queue4, refs:" + queue4.memoryRefCount() + " dels:" + queue4.getDeliveringCount());
-         log.trace("queue5, refs:" + queue5.memoryRefCount() + " dels:" + queue5.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES - 11, queue1.memoryRefCount());
-         assertEquals(0, queue1.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES - 11, queue2.memoryRefCount());
-         assertEquals(0, queue2.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES - 15, queue3.memoryRefCount());
-         assertEquals(0, queue3.getDeliveringCount());
-
-         assertEquals(NUM_MESSAGES - 20, queue4.memoryRefCount());
-         assertEquals(0, queue4.getDeliveringCount());
-
-         assertEquals(1, queue5.memoryRefCount());
-         assertEquals(1, queue5.getDeliveringCount());
-
-         acknowledgeAll(receiver5);
-
-         assertEquals(0, queue5.getDeliveringCount());
-
-         receiver5.setMaxRefs(0);
-
-         assertTrue(office1.getHoldingTransactions().isEmpty());
-         assertTrue(office2.getHoldingTransactions().isEmpty());
-         assertTrue(office3.getHoldingTransactions().isEmpty());
-         assertTrue(office4.getHoldingTransactions().isEmpty());
-         assertTrue(office5.getHoldingTransactions().isEmpty());
-
-         // From queue 4 consume everything else
-
-         int num = NUM_MESSAGES - 15 + NUM_MESSAGES - 20 + NUM_MESSAGES - 11 + NUM_MESSAGES - 11 + 1;
-         receiver4.setMaxRefs(num);
-         queue4.deliver();
-         readOK = receiver4.waitForHandleInvocations(num, 20000);
-         assertTrue(readOK);
-
-         Thread.sleep(2000);
-
-         log.trace("Here are the sizes 6:");
-         log.trace("queue1, refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
-         log.trace("queue2, refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
-         log.trace("queue3, refs:" + queue3.memoryRefCount() + " dels:" + queue3.getDeliveringCount());
-         log.trace("queue4, refs:" + queue4.memoryRefCount() + " dels:" + queue4.getDeliveringCount());
-         log.trace("queue5, refs:" + queue5.memoryRefCount() + " dels:" + queue5.getDeliveringCount());
-
-         assertEquals(0, queue1.memoryRefCount());
-         assertEquals(0, queue1.getDeliveringCount());
-
-         assertEquals(0, queue2.memoryRefCount());
-         assertEquals(0, queue2.getDeliveringCount());
-
-         assertEquals(0, queue3.memoryRefCount()); // <- sometimes, there is still 1 message left in this queue
-         assertEquals(0, queue3.getDeliveringCount());
-
-         assertEquals(0, queue4.memoryRefCount());
-         assertEquals(NUM_MESSAGES - 15 + NUM_MESSAGES - 20 + NUM_MESSAGES - 11 + NUM_MESSAGES - 11 + 1, queue4.getDeliveringCount());
-
-         assertEquals(0, queue5.memoryRefCount());
-         assertEquals(0, queue5.getDeliveringCount());
-
-         acknowledgeAll(receiver4);
-
-         assertEquals(0, queue4.getDeliveringCount());
-
-         assertTrue(office1.getHoldingTransactions().isEmpty());
-         assertTrue(office2.getHoldingTransactions().isEmpty());
-         assertTrue(office3.getHoldingTransactions().isEmpty());
-         assertTrue(office4.getHoldingTransactions().isEmpty());
-         assertTrue(office5.getHoldingTransactions().isEmpty());
-
-         if (checkNoMessageData())
-         {
-            fail("Message data still in database");
-         }
-      }
-      finally
-      {
-         if (office1 != null)
-         {
-            office1.stop();
-         }
-
-         if (office2 != null)
-         {
-            office2.stop();
-         }
-
-         if (office3 != null)
-         {
-            office3.stop();
-         }
-
-         if (office4 != null)
-         {
-            office4.stop();
-         }
-
-         if (office5 != null)
-         {
-            office5.stop();
-         }
-      }
-   }
-
-   class ThrottleReceiver implements Receiver, Runnable
-   {
-      long pause;
-
-      volatile int totalCount;
-
-      int count;
-
-      int maxSize;
-
-      volatile boolean full;
-
-      Executor executor;
-
-      List dels;
-
-      Channel queue;
-
-      int getTotalCount()
-      {
-         return totalCount;
-      }
-
-      ThrottleReceiver(Channel queue, long pause, int maxSize)
-      {
-         this.queue = queue;
-
-         this.pause = pause;
-
-         this.maxSize = maxSize;
-
-         this.executor = new QueuedExecutor();
-
-         this.dels = new ArrayList();
-      }
-
-      public Delivery handle(DeliveryObserver observer, MessageReference reference, Transaction tx)
-      {
-         if (full)
-         {
-            return null;
-         }
-
-         //log.trace(this + " got ref");
-
-         //log.trace("cnt:" + totalCount);
-
-         SimpleDelivery del = new SimpleDelivery(observer, reference);
-
-         dels.add(del);
-
-         count++;
-
-         totalCount++;
-
-         if (count == maxSize)
-         {
-            full = true;
-
-            count = 0;
-
-            try
-            {
-               executor.execute(this);
-            }
-            catch (InterruptedException e)
-            {
-               //Ignore
-            }
-         }
-
-         return del;
-
-      }
-
-      public void run()
-      {
-         //Simulate processing of messages
-
-         try
-         {
-            Thread.sleep(pause);
-         }
-         catch (InterruptedException e)
-         {
-            //Ignore
-         }
-
-         Iterator iter = dels.iterator();
-
-         while (iter.hasNext())
-         {
-            Delivery del = (Delivery) iter.next();
-
-            try
-            {
-               del.acknowledge(null);
-            }
-            catch (Throwable t)
-            {
-               //Ignore
-            }
-         }
-
-         dels.clear();
-
-         full = false;
-
-         queue.deliver();
-      }
-
-   }
-
-   private void acknowledgeAll(SimpleReceiver receiver) throws Throwable
-   {
-      List messages = receiver.getMessages();
-
-      Iterator iter = messages.iterator();
-
-      while (iter.hasNext())
-      {
-         Message msg = (Message) iter.next();
-
-         receiver.acknowledge(msg, null);
-      }
-
-      receiver.clear();
-   }
-
-
-   // Private --------------------------------------------------------------------------------------
-
-   // Inner classes --------------------------------------------------------------------------------
-
-}
-
-
-
-

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RoundRobinRouterTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RoundRobinRouterTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RoundRobinRouterTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,629 +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.postoffice.cluster;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.DeliveryObserver;
-import org.jboss.messaging.core.Filter;
-import org.jboss.messaging.core.Queue;
-import org.jboss.messaging.core.Receiver;
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.plugin.postoffice.cluster.ClusterRouter;
-import org.jboss.messaging.core.plugin.postoffice.cluster.ClusteredQueue;
-import org.jboss.messaging.core.plugin.postoffice.cluster.QueueStats;
-import org.jboss.messaging.core.plugin.postoffice.cluster.RoundRobinRouter;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.test.messaging.core.SimpleReceiver;
-import org.jboss.test.messaging.core.plugin.base.PostOfficeTestBase;
-import org.jboss.test.messaging.util.CoreMessageFactory;
-
-/**
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 2386 $</tt>
- * 
- * TODO Need to add tests for failed over queues to this
- *
- * $Id: DefaultRouterTest.java 2386 2007-02-21 18:07:44Z timfox $
- *
- */
-public class RoundRobinRouterTest extends PostOfficeTestBase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-   
-   // Constructors --------------------------------------------------
-
-   public RoundRobinRouterTest(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-   }
-
-   public void tearDown() throws Exception
-   {      
-      super.tearDown();
-   }
-   
-   public void testSize() throws Exception
-   {
-      RoundRobinRouter dr = new RoundRobinRouter();
-      
-      ClusteredQueue queue1 = new SimpleClusteredQueue(true);
-      dr.add(queue1);
-      
-      assertEquals(1, dr.getNumberOfReceivers());
-      assertEquals(1, dr.getQueues().size());
-      
-      ClusteredQueue queue2 = new SimpleClusteredQueue(false);
-      dr.add(queue2);
-      
-      assertEquals(2, dr.getNumberOfReceivers());
-      assertEquals(2, dr.getQueues().size());
-      
-      ClusteredQueue queue3 = new SimpleClusteredQueue(false);
-      dr.add(queue3);
-      
-      assertEquals(3, dr.getNumberOfReceivers());
-      assertEquals(3, dr.getQueues().size());
-      
-      dr.remove(queue3);
-      
-      assertEquals(2, dr.getNumberOfReceivers());
-      assertEquals(2, dr.getQueues().size());
-      
-      dr.remove(queue2);
-      
-      assertEquals(1, dr.getNumberOfReceivers());
-      assertEquals(1, dr.getQueues().size());
-      
-      dr.remove(queue1);
-      
-      assertEquals(0, dr.getNumberOfReceivers());
-      assertTrue(dr.getQueues().isEmpty());
-      
-   }
-   
-   // The router only has a local queue
-   public void testRouterOnlyLocal() throws Exception
-   {
-      RoundRobinRouter dr = new RoundRobinRouter();
-                    
-      ClusteredQueue queue = new SimpleClusteredQueue(true);
-      
-      SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      queue.add(receiver1);
-               
-      dr.add(queue);
-      
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver1);
-   }
-   
-   //The router has only one non local clustered queue
-   public void testRouterOnlyOneNonLocalClustered() throws Exception
-   {
-      RoundRobinRouter dr = new RoundRobinRouter();
-                    
-      ClusteredQueue queue = new SimpleClusteredQueue(false);
-      
-      SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      queue.add(receiver1);
-      
-      dr.add(queue);
-      
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver1);              
-   }
-   
-   //The router has only one non local non clustered queue
-   public void testRouterOnlyOneNonLocalNonClustered() throws Exception
-   {
-      RoundRobinRouter dr = new RoundRobinRouter();
-                    
-      ClusteredQueue queue = new SimpleClusteredQueue(false);
-      
-      SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      queue.add(receiver1);
-      
-      dr.add(queue);
-      
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver1);              
-   }
-   
-   //The router has multiple non local queues and no local queue
-   public void testRouterMultipleNonLocal() throws Exception
-   {
-      RoundRobinRouter dr = new RoundRobinRouter();
-                   
-      ClusteredQueue remote1 = new SimpleClusteredQueue(false);
-     
-      SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      remote1.add(receiver1);
-      
-      dr.add(remote1);
-      
-      
-      ClusteredQueue remote2 = new SimpleClusteredQueue(false);
-      
-      SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      remote2.add(receiver2);
-      
-      dr.add(remote2);
-      
-      
-      ClusteredQueue remote3 = new SimpleClusteredQueue(false);
-      
-      SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      remote3.add(receiver3);
-      
-      dr.add(remote3);
-      
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver2);
-      
-      sendAndCheck(dr, receiver3);
-      
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver2);
-      
-      sendAndCheck(dr, receiver3);
-   }
-   
-   
-   // The router has one local with consumer and one non local queue with consumer
-   public void testRouterOneLocalOneNonLocal() throws Exception
-   {
-      RoundRobinRouter dr = new RoundRobinRouter();
-                             
-      ClusteredQueue remote1 = new SimpleClusteredQueue(false);
-     
-      SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      remote1.add(receiver1);
-      
-      dr.add(remote1);
-      
-      ClusteredQueue queue = new SimpleClusteredQueue(true);
-      
-      SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      queue.add(receiver2);
-      
-      dr.add(queue);
-
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver2);
-      
-      sendAndCheck(dr, receiver1);  
-      
-      sendAndCheck(dr, receiver2); 
-      
-      sendAndCheck(dr, receiver1); 
-   }
-   
-   // The router has multiple non local queues with consumers and one local queue
-   public void testRouterMultipleNonLocalOneLocal() throws Exception
-   {
-      RoundRobinRouter dr = new RoundRobinRouter();            
-                  
-      ClusteredQueue remote1 = new SimpleClusteredQueue(false);
-      
-      SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      remote1.add(receiver1);
-      
-      dr.add(remote1);
-      
-      
-      ClusteredQueue remote2 = new SimpleClusteredQueue(false);
-      
-      SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      remote2.add(receiver2);
-      
-      dr.add(remote2);
-      
-      
-      ClusteredQueue remote3 = new SimpleClusteredQueue(false);
-      
-      SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      remote3.add(receiver3);
-      
-      dr.add(remote3);
-      
-      
-      ClusteredQueue queue = new SimpleClusteredQueue(true);
-            
-      SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);
-      
-      queue.add(receiver4);
-      
-      dr.add(queue);
-      
-      
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver2);
-      
-      sendAndCheck(dr, receiver3);
-      
-      sendAndCheck(dr, receiver4);
-      
-      sendAndCheck(dr, receiver1);
-      
-      sendAndCheck(dr, receiver2);
-      
-      sendAndCheck(dr, receiver3);
-      
-      sendAndCheck(dr, receiver4);
-      
-      sendAndCheck(dr, receiver1);
-   }
-   
-   
-   private long nextId;
-   
-   private void sendAndCheck(ClusterRouter router, SimpleReceiver receiver) throws Exception
-   {
-      Message msg = CoreMessageFactory.createCoreMessage(nextId++, false, null);      
-      
-      MessageReference ref = ms.reference(msg);         
-      
-      Delivery del = router.handle(null, ref, null);
-      
-      assertNotNull(del);
-      
-      assertTrue(del.isSelectorAccepted());
-            
-      Thread.sleep(250);
-      
-      List msgs = receiver.getMessages();
-      
-      assertNotNull(msgs);
-      
-      assertEquals(1, msgs.size());
-      
-      Message msgRec = (Message)msgs.get(0);
-      
-      assertTrue(msg == msgRec);  
-      
-      receiver.clear();
-   }
-   
-   // Private -------------------------------------------------------
-   
-   
-   // Inner classes -------------------------------------------------
-   
-   class SimpleNonClusteredQueue implements Queue
-   {
-      private Receiver receiver;
-      
-      private List refs = new ArrayList();       
-
-      public Filter getFilter()
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public String getName()
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public boolean isClustered()
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public boolean acceptReliableMessages()
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public void activate()
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public List browse()
-      {
-         List msgs = new ArrayList();
-         
-         Iterator iter = refs.iterator();
-         
-         while (iter.hasNext())
-         {
-            MessageReference ref = (MessageReference)iter.next();
-            
-            msgs.add(ref);
-         }
-         
-         return msgs;
-      }
-
-      public List browse(Filter filter)
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public void clear()
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public void close()
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public void deactivate()
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public void deliver()
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public List delivering(Filter filter)
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public long getChannelID()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public boolean isActive()
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public boolean isRecoverable()
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public void load() throws Exception
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public int getMessageCount()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public void removeAllReferences() throws Throwable
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public List undelivered(Filter filter)
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public void unload() throws Exception
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public Delivery handle(DeliveryObserver observer, MessageReference reference, Transaction tx)
-      {
-         if (receiver != null)
-         {
-            // Send to receiver
-            return receiver.handle(observer, reference, tx);
-         }
-         else
-         {
-            // Store internally
-            refs.add(reference);
-            
-            return new SimpleDelivery(observer, reference);
-         }
-         
-      
-      }
-
-      public void acknowledge(Delivery d, Transaction tx) throws Throwable
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public void cancel(Delivery d) throws Throwable
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public boolean add(Receiver receiver)
-      {
-         this.receiver = receiver;
-         
-         return true;
-      }
-
-      public boolean contains(Receiver receiver)
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public Iterator iterator()
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public int getNumberOfReceivers()
-      {
-         if (receiver != null)
-         {
-            return 1;
-         }
-         else
-         {
-            return 0;
-         }
-      }
-
-      public boolean remove(Receiver receiver)
-      {
-         // TODO Auto-generated method stub
-         return false;
-      }
-
-      public List recoverDeliveries(List messageIds)
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public void addDelivery(Delivery del)
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public int getDeliveringCount()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public int getMaxSize()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public int getMessagesAdded()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public void setMaxSize(int newSize)
-      {
-         // TODO Auto-generated method stub
-         
-      }
-
-      public int getScheduledCount()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }   	
-   }
-   
-   class SimpleClusteredQueue extends SimpleNonClusteredQueue implements ClusteredQueue
-   {
-      private boolean local;
-           
-      SimpleClusteredQueue(boolean local)
-      {
-         this.local = local;
-      }
-
-      public int getNodeId()
-      {
-         // TODO Auto-generated method stub
-         return 0;
-      }
-
-      public QueueStats getStats()
-      {
-         // TODO Auto-generated method stub
-         return null;
-      }
-
-      public boolean isLocal()
-      {
-         return local;
-      }
-   }
-   
-
-}
-
-
-

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/SimpleJChannelFactory.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/SimpleJChannelFactory.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/SimpleJChannelFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,97 +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.postoffice.cluster;
-
-import org.jgroups.JChannel;
-import org.jboss.messaging.core.plugin.postoffice.cluster.jchannelfactory.JChannelFactory;
-
-/**
- * A JChannelFactory that will use String JChannel configurations to create JChannel instances.
- *
- * @author <a href="mailto:clebert.suconic at jboss.org">Clebert Suconic</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class SimpleJChannelFactory implements JChannelFactory
-{
-   // Constants ------------------------------------------------------------------------------------
-
-   // Static ---------------------------------------------------------------------------------------
-
-   // Attributes -----------------------------------------------------------------------------------
-
-   String asyncConfig;
-   String syncConfig;
-
-   // Constructors ---------------------------------------------------------------------------------
-
-   public SimpleJChannelFactory(String syncConfig, String asyncConfig)
-   {
-      this.syncConfig = syncConfig;
-      this.asyncConfig = asyncConfig;
-   }
-
-   // JChannelFactory ------------------------------------------------------------------------------
-
-   public JChannel createSyncChannel() throws Exception
-   {
-      return new JChannel(syncConfig);
-   }
-
-   public JChannel createASyncChannel() throws Exception
-   {
-      return new JChannel(asyncConfig);
-   }
-
-   // Public ---------------------------------------------------------------------------------------
-
-   public String getAsyncConfig()
-   {
-      return asyncConfig;
-   }
-
-   public void setAsyncConfig(String asyncConfig)
-   {
-      this.asyncConfig = asyncConfig;
-   }
-
-   public String getSyncConfig()
-   {
-      return syncConfig;
-   }
-
-   public void setSyncConfig(String syncConfig)
-   {
-      this.syncConfig = syncConfig;
-   }
-
-   // Package protected ----------------------------------------------------------------------------
-
-   // Protected ------------------------------------------------------------------------------------
-
-   // Private --------------------------------------------------------------------------------------
-
-   // Inner classes --------------------------------------------------------------------------------
-
-}

Modified: trunk/tests/src/org/jboss/test/messaging/jms/AcknowledgementTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/AcknowledgementTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/AcknowledgementTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -714,9 +714,8 @@
       conn.close();
    }
       
-   public void testDupsOKAcknowledge() throws Exception
-   { 
-      
+   public void testDupsOKAcknowledgeQueue() throws Exception
+   {       
       final int BATCH_SIZE = 10;
       
       String mbeanConfig =
@@ -737,65 +736,155 @@
       ServerManagement.invoke(on, "create", new Object[0], new String[0]);
       ServerManagement.invoke(on, "start", new Object[0], new String[0]);
       
-      ConnectionFactory myCF = (ConnectionFactory)initialContext.lookup("/mycf");
+      Connection conn = null;
       
-      Connection conn = myCF.createConnection();
-
-      Session producerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-      MessageProducer producer = producerSess.createProducer(queue);
-
-      Session consumerSess = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
-      MessageConsumer consumer = consumerSess.createConsumer(queue);
-      conn.start();
-
-      //Send some messages
-      for (int i = 0; i < 19; i++)
+      try
       {
-         Message m = producerSess.createMessage();
-         producer.send(m);
+	      
+	      ConnectionFactory myCF = (ConnectionFactory)initialContext.lookup("/mycf");
+	      
+	      conn = myCF.createConnection();
+	
+	      Session producerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+	      MessageProducer producer = producerSess.createProducer(queue);
+	
+	      Session consumerSess = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
+	      MessageConsumer consumer = consumerSess.createConsumer(queue);
+	      conn.start();
+	
+	      //Send some messages
+	      for (int i = 0; i < 19; i++)
+	      {
+	         Message m = producerSess.createMessage();
+	         producer.send(m);
+	      }
+	      
+	      assertRemainingMessages(19);
+	
+	      log.trace("Sent messages");
+	
+	      Message m = null;
+	      for (int i = 0; i < 10; i++)
+	      {
+	         m = consumer.receive(200);
+	         
+	         assertNotNull(m);
+	          
+	         if (i == 9)
+	         {
+	            assertRemainingMessages(9);
+	         }
+	         else
+	         {
+	            assertRemainingMessages(19);
+	         }
+	      }
+	      
+	      for (int i = 0; i < 9; i++)
+	      {
+	         m = consumer.receive(200);
+	         
+	         assertNotNull(m);
+	         
+	         assertRemainingMessages(9);
+	      }
+	      
+	      //Make sure the last are acked on close
+	      
+	      consumerSess.close();
+	      
+	      assertRemainingMessages(0);
       }
+      finally
+      {
       
-      assertRemainingMessages(19);
+      	if (conn != null)
+      	{
+      		conn.close();
+      	}
+      	
+      	ServerManagement.invoke(on, "stop", new Object[0], new String[0]);
+         ServerManagement.invoke(on, "destroy", new Object[0], new String[0]);
+      }
+      
 
-      log.trace("Sent messages");
+   }
+   
+   
+   public void testDupsOKAcknowledgeTopic() throws Exception
+   {       
+      final int BATCH_SIZE = 10;
+      
+      String mbeanConfig =
+         "<mbean code=\"org.jboss.jms.server.connectionfactory.ConnectionFactory\"\n" +
+         "       name=\"jboss.messaging.destination:service=MyConnectionFactory2\"\n" +
+         "       xmbean-dd=\"xmdesc/ConnectionFactory-xmbean.xml\">\n" +
+         "       <depends optional-attribute-name=\"ServerPeer\">jboss.messaging:service=ServerPeer</depends>\n" +
+         "       <depends optional-attribute-name=\"Connector\">jboss.messaging:service=Connector,transport=bisocket</depends>\n" +
+         "       <attribute name=\"JNDIBindings\">\n" +
+         "          <bindings>\n" +
+         "            <binding>/mycf</binding>\n" +
+         "          </bindings>\n" +
+         "       </attribute>\n" +
+         "       <attribute name=\"DupsOKBatchSize\">" + BATCH_SIZE  + "</attribute>" +
+         " </mbean>";
 
-      Message m = null;
-      for (int i = 0; i < 10; i++)
+      ObjectName on = ServerManagement.deploy(mbeanConfig);
+      ServerManagement.invoke(on, "create", new Object[0], new String[0]);
+      ServerManagement.invoke(on, "start", new Object[0], new String[0]);
+      
+      Connection conn = null;
+      
+      try
       {
-         m = consumer.receive(200);
-         
-         assertNotNull(m);
-          
-         if (i == 9)
-         {
-            assertRemainingMessages(9);
-         }
-         else
-         {
-            assertRemainingMessages(19);
-         }
+	      
+	      ConnectionFactory myCF = (ConnectionFactory)initialContext.lookup("/mycf");
+	      
+	      conn = myCF.createConnection();
+	
+	      Session producerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+	      MessageProducer producer = producerSess.createProducer(topic);
+	
+	      Session consumerSess = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
+	      MessageConsumer consumer = consumerSess.createConsumer(topic);
+	      conn.start();
+	
+	      //Send some messages
+	      for (int i = 0; i < 19; i++)
+	      {
+	         Message m = producerSess.createMessage();
+	         producer.send(m);
+	      }
+	      
+	      log.trace("Sent messages");
+	
+	      Message m = null;
+	      for (int i = 0; i < 19; i++)
+	      {
+	         m = consumer.receive(200);
+	         
+	         assertNotNull(m);
+	      }
+	      	   	      
+	      consumerSess.close();
       }
+      finally
+      {
       
-      for (int i = 0; i < 9; i++)
-      {
-         m = consumer.receive(200);
-         
-         assertNotNull(m);
-         
-         assertRemainingMessages(9);
+      	if (conn != null)
+      	{
+      		conn.close();
+      	}
+      	
+      	ServerManagement.invoke(on, "stop", new Object[0], new String[0]);
+         ServerManagement.invoke(on, "destroy", new Object[0], new String[0]);
       }
       
-      //Make sure the last are acked on close
-      
-      consumerSess.close();
-      
-      assertRemainingMessages(0);
-      
-      conn.close();
 
    }
-
-
+   
+   
+   
 	/*
 	 * Send some messages, consume them and verify the messages are not sent upon recovery
 	 *

Modified: trunk/tests/src/org/jboss/test/messaging/jms/DLQTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/DLQTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/DLQTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -35,6 +35,7 @@
 import javax.jms.Queue;
 import javax.jms.Session;
 import javax.jms.TextMessage;
+import javax.jms.Topic;
 import javax.management.ObjectName;
 import javax.naming.InitialContext;
 import javax.naming.NameNotFoundException;
@@ -101,7 +102,7 @@
       
       assertEquals("/queue/DLQ", jndiName);
       
-      org.jboss.messaging.core.Queue dlq = ServerManagement.getServer().getServerPeer().getDefaultDLQInstance();
+      org.jboss.messaging.core.contract.Queue dlq = ServerManagement.getServer().getServerPeer().getDefaultDLQInstance();
 
       assertNotNull(dlq);
 
@@ -133,7 +134,7 @@
          return;
       }
       
-      org.jboss.messaging.core.Queue dlq = ServerManagement.getServer().getServerPeer().getDefaultDLQInstance();
+      org.jboss.messaging.core.contract.Queue dlq = ServerManagement.getServer().getServerPeer().getDefaultDLQInstance();
 
       assertNull(dlq);
 
@@ -501,11 +502,11 @@
 
       try
       {
-         int maxDeliveryAttempts = getDefaultMaxDeliveryAttempts() + 5;
+         int maxDeliveryAttempts = getDefaultMaxDeliveryAttempts() - 5;
          setMaxDeliveryAttempts(
                new ObjectName("jboss.messaging.destination:service=Queue,name=" + QUEUE_NAME),
                maxDeliveryAttempts);
-         testMaxDeliveryAttempts("/queue/" + QUEUE_NAME, maxDeliveryAttempts);
+         testMaxDeliveryAttempts("/queue/" + QUEUE_NAME, maxDeliveryAttempts, true);
       }
       finally
       {
@@ -521,12 +522,12 @@
 
       try
       {
-         int maxDeliveryAttempts = getDefaultMaxDeliveryAttempts() + 5;
+         int maxDeliveryAttempts = getDefaultMaxDeliveryAttempts() - 5;
          setMaxDeliveryAttempts(
                new ObjectName("jboss.messaging.destination:service=Topic,name=" + TOPIC_NAME),
                maxDeliveryAttempts);
 
-         testMaxDeliveryAttempts("/topic/" + TOPIC_NAME, maxDeliveryAttempts);
+         testMaxDeliveryAttempts("/topic/" + TOPIC_NAME, maxDeliveryAttempts, false);
       }
       finally
       {
@@ -547,7 +548,7 @@
                -1);
 
          // Check that defaultMaxDeliveryAttempts takes effect
-         testMaxDeliveryAttempts("/queue/" + QUEUE_NAME, getDefaultMaxDeliveryAttempts());
+         testMaxDeliveryAttempts("/queue/" + QUEUE_NAME, getDefaultMaxDeliveryAttempts(), true);
       }
       finally
       {
@@ -568,7 +569,7 @@
                -1);
 
          // Check that defaultMaxDeliveryAttempts takes effect
-         testMaxDeliveryAttempts("/topic/" + TOPIC_NAME, getDefaultMaxDeliveryAttempts());
+         testMaxDeliveryAttempts("/topic/" + TOPIC_NAME, getDefaultMaxDeliveryAttempts(), false);
       }
       finally
       {
@@ -892,7 +893,7 @@
             Integer.toString(maxDeliveryAttempts));
    }
    
-   protected void testMaxDeliveryAttempts(String destJndiName, int destMaxDeliveryAttempts) throws Exception
+   protected void testMaxDeliveryAttempts(String destJndiName, int destMaxDeliveryAttempts, boolean queue) throws Exception
    {
       ServerManagement.deployQueue("DLQ");
       Queue dlq = (Queue) ic.lookup("/queue/DLQ");
@@ -902,14 +903,29 @@
       
       Connection conn = cf.createConnection();
       
+      if (!queue)
+      {
+      	conn.setClientID("wib123");
+      }
+      
       try
       {
          // Create the consumer before the producer so that the message we send doesn't
          // get lost if the destination is a Topic.
          Session consumingSession = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);         
-         MessageConsumer destinationConsumer = consumingSession.createConsumer(destination);
+         MessageConsumer destinationConsumer;
          
+         if (queue)
          {
+            destinationConsumer = consumingSession.createConsumer(destination);
+         }
+         else
+         {
+         	//For topics we only keep a delivery record on the server side for durable subs         	
+         	destinationConsumer = consumingSession.createDurableSubscriber((Topic)destination, "testsub1");
+         }
+         
+         {
             Session producingSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
             MessageProducer prod = producingSession.createProducer(destination);
             TextMessage tm = producingSession.createTextMessage("Message");
@@ -920,7 +936,7 @@
 
          // Make delivery attempts up to the maximum. The message should not end up in the DLQ.
          for (int i = 0; i < destMaxDeliveryAttempts; i++)
-         {
+         {         	         
             TextMessage tm = (TextMessage)destinationConsumer.receive(1000);
             assertNotNull("No message received on delivery attempt number " + (i + 1), tm);
             assertEquals("Message", tm.getText());
@@ -942,6 +958,13 @@
          assertNotNull(m);
          assertTrue(m instanceof TextMessage);
          assertEquals("Message", ((TextMessage) m).getText());
+         
+         if (!queue)
+         {
+         	destinationConsumer.close();
+         	
+         	consumingSession.unsubscribe("testsub1");
+         }
       }
       finally
       {

Modified: trunk/tests/src/org/jboss/test/messaging/jms/ExpiryQueueTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/ExpiryQueueTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/ExpiryQueueTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -106,7 +106,7 @@
          
          assertEquals("/queue/ExpiryQueue", jndiName);
          
-         org.jboss.messaging.core.Queue expiryQueue = ServerManagement.getServer().getServerPeer().getDefaultExpiryQueueInstance();
+         org.jboss.messaging.core.contract.Queue expiryQueue = ServerManagement.getServer().getServerPeer().getDefaultExpiryQueueInstance();
    
          assertNotNull(expiryQueue);
    
@@ -136,7 +136,7 @@
          return;
       }
       
-      org.jboss.messaging.core.Queue expiryQueue = ServerManagement.getServer().getServerPeer().getDefaultExpiryQueueInstance();
+      org.jboss.messaging.core.contract.Queue expiryQueue = ServerManagement.getServer().getServerPeer().getDefaultExpiryQueueInstance();
 
       assertNull(expiryQueue);
 

Modified: trunk/tests/src/org/jboss/test/messaging/jms/MessageCleanupTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/MessageCleanupTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/MessageCleanupTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -40,7 +40,7 @@
 import javax.transaction.TransactionManager;
 
 import org.jboss.jms.client.JBossConnectionFactory;
-import org.jboss.messaging.core.message.SimpleMessageStore;
+import org.jboss.messaging.core.impl.message.SimpleMessageStore;
 import org.jboss.test.messaging.MessagingTestCase;
 import org.jboss.test.messaging.tools.ServerManagement;
 import org.jboss.tm.TransactionManagerService;

Modified: trunk/tests/src/org/jboss/test/messaging/jms/PersistenceTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/PersistenceTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/PersistenceTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -468,12 +468,14 @@
       MessageProducer p = s.createProducer(thisTopic);
       p.setDeliveryMode(DeliveryMode.PERSISTENT);
       TextMessage tm = s.createTextMessage("thebody");
+      
       p.send(tm);
       log.debug("message sent");
 
       conn.close();
 
       log.debug("stopping the server");
+
       ServerManagement.stopServerPeer();
 
       try

Modified: trunk/tests/src/org/jboss/test/messaging/jms/ReferencingTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/ReferencingTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/ReferencingTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -31,9 +31,9 @@
 
 import org.jboss.jms.client.JBossConnectionFactory;
 import org.jboss.jms.message.MessageProxy;
-import org.jboss.messaging.core.message.MessageReference;
-import org.jboss.messaging.core.message.SimpleMessageReference;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
+import org.jboss.messaging.core.contract.MessageReference;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.impl.message.SimpleMessageReference;
 import org.jboss.test.messaging.MessagingTestCase;
 import org.jboss.test.messaging.tools.ServerManagement;
 

Modified: trunk/tests/src/org/jboss/test/messaging/jms/WireFormatTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/WireFormatTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/WireFormatTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -536,7 +536,7 @@
       public void testSessionCreateConsumerDelegateRequest() throws Exception
       {
          RequestSupport req =
-            new SessionCreateConsumerDelegateRequest(23, (byte)77, new JBossQueue("wibble"), null, false, null, false);
+            new SessionCreateConsumerDelegateRequest(23, (byte)77, new JBossQueue("wibble"), null, false, null, false, true);
                  
          testPacket(req, PacketSupport.REQ_SESSION_CREATECONSUMERDELEGATE);                           
       } 

Modified: trunk/tests/src/org/jboss/test/messaging/jms/clustering/ClusterEventNotificationListener.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/clustering/ClusterEventNotificationListener.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/clustering/ClusterEventNotificationListener.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -6,14 +6,14 @@
  */
 package org.jboss.test.messaging.jms.clustering;
 
-import EDU.oswego.cs.dl.util.concurrent.Slot;
-
+import javax.management.Notification;
 import javax.management.NotificationListener;
-import javax.management.Notification;
 
-import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
 import org.jboss.logging.Logger;
+import org.jboss.messaging.core.impl.postoffice.MessagingPostOffice;
 
+import EDU.oswego.cs.dl.util.concurrent.Slot;
+
 /**
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
  * @version <tt>$Revision$</tt>
@@ -48,7 +48,7 @@
 
       log.info("received " + type + " notification");
 
-      if (ClusteredPostOffice.VIEW_CHANGED_NOTIFICATION.equals(type))
+      if (MessagingPostOffice.VIEW_CHANGED_NOTIFICATION.equals(type))
       {
          try
          {
@@ -59,7 +59,7 @@
             log.error(e);
          }
       }
-      else if (ClusteredPostOffice.FAILOVER_COMPLETED_NOTIFICATION.equals(type))
+      else if (MessagingPostOffice.FAILOVER_COMPLETED_NOTIFICATION.equals(type))
       {
          try
          {

Modified: trunk/tests/src/org/jboss/test/messaging/jms/clustering/ClusterViewUpdateTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/clustering/ClusterViewUpdateTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/clustering/ClusterViewUpdateTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -71,7 +71,9 @@
 
       assertEquals(1, getServerId(conn1));
 
+      log.info("*** killing server");
       ServerManagement.killAndWait(1);
+      log.info("killed server");
 
       log.info("sleeping 5 secs ...");
       Thread.sleep(5000);
@@ -80,16 +82,18 @@
       assertEquals(2, cfDelegate.getDelegates().length);
       conn.close();
 
-      log.info("sleeping 25 secs ...");
-      Thread.sleep(25000);
+      log.info("sleeping 10 secs ...");
+      Thread.sleep(10000);
 
-      // Second part, verifies a possible racing condition on failoverMap and handleFilover
+      // Second part, verifies a possible race condition on failoverMap and handleFilover
 
       log.info("ServerId=" + getServerId(conn1));
       assertTrue(1 != getServerId(conn1));
 
       //Session sess = conn1.createSession(true, Session.SESSION_TRANSACTED);
       conn1.close();
+      
+      log.info("Done!!");
 
    }
 
@@ -136,8 +140,8 @@
       conn.close();
       httpConn.close();
 
-      log.info("sleeping 25 secs ...");
-      Thread.sleep(25000);
+      log.info("sleeping 10 secs ...");
+      Thread.sleep(10000);
 
       // Second part, verifies a possible racing condition on failoverMap and handleFilover
 
@@ -178,7 +182,7 @@
 
       ServerManagement.killAndWait(1);
 
-      Thread.sleep(15000);
+      Thread.sleep(10000);
 
       // This will force Failover from Valve to kick in
       conn1.createSession(true, Session.SESSION_TRANSACTED);

Modified: trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedDestinationsTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedDestinationsTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedDestinationsTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -21,6 +21,9 @@
  */
 package org.jboss.test.messaging.jms.clustering;
 
+import java.util.HashSet;
+import java.util.Set;
+
 import javax.jms.Connection;
 import javax.jms.DeliveryMode;
 import javax.jms.Message;
@@ -60,14 +63,14 @@
 
    // Public --------------------------------------------------------
 
-   public void testClusteredQueueLocalConsumerNonPersistent() throws Exception
+   public void testClusteredQueueNonPersistent() throws Exception
    {
-      clusteredQueueLocalConsumer(false);
+      clusteredQueue(false);
    }
 
-   public void testClusteredQueueLocalConsumerPersistent() throws Exception
+   public void testClusteredQueuePersistent() throws Exception
    {
-      clusteredQueueLocalConsumer(true);
+      clusteredQueue(true);
    }
 
    public void testClusteredTopicNonDurableNonPersistent() throws Exception
@@ -138,131 +141,138 @@
       super.tearDown();
    }
 
-   /*
-    * Create a consumer on each queue on each node.
-    * Send messages in turn from all nodes.
-    * Ensure that the local consumer gets the message
-    */
-   protected void clusteredQueueLocalConsumer(boolean persistent) throws Exception
+   protected void clusteredQueue(boolean persistent) throws Exception
    {
+      Connection conn0 = null;
       Connection conn1 = null;
       Connection conn2 = null;
-      Connection conn3 = null;
 
       try
       {
          //This will create 3 different connection on 3 different nodes, since
          //the cf is clustered
+         conn0 = cf.createConnection();
          conn1 = cf.createConnection();
          conn2 = cf.createConnection();
-         conn3 = cf.createConnection();
          
          log.info("Created connections");
          
-         checkConnectionsDifferentServers(new Connection[] {conn1, conn2, conn3});
+         checkConnectionsDifferentServers(new Connection[] {conn0, conn1, conn2});
 
+         Session sess0 = conn0.createSession(false, Session.AUTO_ACKNOWLEDGE);
          Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
          Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         Session sess3 = conn3.createSession(false, Session.AUTO_ACKNOWLEDGE);
          
          log.info("Created sessions");
 
-         MessageConsumer cons1 = sess1.createConsumer(queue[0]);
-         MessageConsumer cons2 = sess2.createConsumer(queue[1]);
-         MessageConsumer cons3 = sess3.createConsumer(queue[2]);
+         MessageConsumer cons0 = sess0.createConsumer(queue[0]);
+         MessageConsumer cons1 = sess1.createConsumer(queue[1]);
+         MessageConsumer cons2 = sess2.createConsumer(queue[2]);
          
          log.info("Created consumers");
 
+         conn0.start();
          conn1.start();
          conn2.start();
-         conn3.start();
 
          // Send at node 0
 
-         MessageProducer prod = sess1.createProducer(queue[0]);
+         MessageProducer prod0 = sess0.createProducer(queue[0]);
 
-         prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+         prod0.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
 
          final int NUM_MESSAGES = 100;
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
-            TextMessage tm = sess1.createTextMessage("message" + i);
+            TextMessage tm = sess0.createTextMessage("message" + i);
 
-            prod.send(tm);
+            prod0.send(tm);
          }
          
          log.info("Sent messages");
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
-            TextMessage tm = (TextMessage)cons1.receive(1000);
+            TextMessage tm = (TextMessage)cons0.receive(1000);
 
             assertNotNull(tm);
             
             assertEquals("message" + i, tm.getText());
          }                 
 
-         Message m = cons2.receive(2000);
+         Message m = cons0.receive(2000);
 
          assertNull(m);
+         
+         m = cons1.receive(2000);
 
-         m = cons3.receive(2000);
+         assertNull(m);
 
+         m = cons2.receive(2000);
+
          assertNull(m);
 
          // Send at node 1
 
-         MessageProducer prod1 = sess2.createProducer(queue[1]);
+         MessageProducer prod1 = sess1.createProducer(queue[1]);
 
          prod1.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
-            TextMessage tm = sess2.createTextMessage("message" + i);
+            TextMessage tm = sess1.createTextMessage("message" + i);
 
             prod1.send(tm);
          }
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
-            TextMessage tm = (TextMessage)cons2.receive(1000);
+            TextMessage tm = (TextMessage)cons1.receive(1000);
 
             assertNotNull(tm);
 
             assertEquals("message" + i, tm.getText());
          }
 
+         m = cons0.receive(2000);
+
+         assertNull(m);
+         
          m = cons1.receive(2000);
 
          assertNull(m);
 
-         m = cons3.receive(2000);
+         m = cons2.receive(2000);
 
          assertNull(m);
 
          // Send at node 2
+         
+         MessageProducer prod2 = sess2.createProducer(queue[2]);
 
-         MessageProducer prod2 = sess3.createProducer(queue[2]);
-
          prod2.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
-            TextMessage tm = sess3.createTextMessage("message" + i);
+            TextMessage tm = sess2.createTextMessage("message" + i);
 
             prod2.send(tm);
          }
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
-            TextMessage tm = (TextMessage)cons3.receive(1000);
+            TextMessage tm = (TextMessage)cons2.receive(1000);
 
             assertNotNull(tm);
 
             assertEquals("message" + i, tm.getText());
          }
 
+         m = cons0.receive(2000);
+
+         assertNull(m);
+         
          m = cons1.receive(2000);
 
          assertNull(m);
@@ -270,9 +280,330 @@
          m = cons2.receive(2000);
 
          assertNull(m);
+         
+         
+         //Now close the consumers at node 0 and node 1
+         
+         cons0.close();
+         
+         cons1.close();
+         
+         //Send more messages at node 0
+         
+         log.info("Sending more at node 0");
+         
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+            TextMessage tm = sess0.createTextMessage("message2-" + i);
+
+            prod0.send(tm);
+         }
+         
+         log.info("Sent messages");
+         
+         // consume them on node2
+
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+            TextMessage tm = (TextMessage)cons2.receive(1000);
+            
+            log.info("*** got message " + tm.getText());
+            
+            assertNotNull(tm);
+            
+            assertEquals("message2-" + i, tm.getText());
+         }                 
+
+         m = cons2.receive(2000);
+
+         assertNull(m);
+         
+         //Send more messages at node 0 and node 1
+         
+         for (int i = 0; i < NUM_MESSAGES / 2; i++)
+         {
+            TextMessage tm = sess0.createTextMessage("message3-" + i);
+
+            prod0.send(tm);
+         }
+         
+         for (int i = NUM_MESSAGES / 2; i < NUM_MESSAGES; i++)
+         {
+            TextMessage tm = sess1.createTextMessage("message3-" + i);
+
+            prod2.send(tm);
+         }
+         
+         //consume them on node 2 - we will get messages from both nodes so the order is undefined
+         
+         Set msgs = new HashSet();
+         
+         TextMessage tm = null;
+         
+         do
+         {
+            tm = (TextMessage)cons2.receive(1000);
+            
+            if (tm != null)
+            {            
+	            log.info("*** got message " + tm.getText());
+	            
+	            assertNotNull(tm);
+	            
+	            msgs.add(tm.getText());
+            }
+         }           
+         while (tm != null);
+
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+         	assertTrue(msgs.contains("message3-" + i));
+         }
+         
+         // Now repeat but this time creating the consumer after send
+         
+         cons2.close();
+         
+         //	Send more messages at node 0 and node 1
+         
+         for (int i = 0; i < NUM_MESSAGES / 2; i++)
+         {
+            tm = sess0.createTextMessage("message3-" + i);
+
+            prod0.send(tm);
+         }
+         
+         for (int i = NUM_MESSAGES / 2; i < NUM_MESSAGES; i++)
+         {
+            tm = sess1.createTextMessage("message3-" + i);
+
+            prod2.send(tm);
+         }
+         
+         cons2 = sess2.createConsumer(queue[2]);
+         
+         //consume them on node 2 - we will get messages from both nodes so the order is undefined
+         
+         msgs = new HashSet();
+         
+         do
+         {
+            tm = (TextMessage)cons2.receive(1000);
+            
+            if (tm != null)
+            {            
+	            log.info("*** got message " + tm.getText());
+	            
+	            assertNotNull(tm);
+	            
+	            msgs.add(tm.getText());
+            }
+         }     
+         while (tm != null);
+
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+         	assertTrue(msgs.contains("message3-" + i));
+         }
+         
+         
+         //Now send messages at node 0 - but consume from node 1 AND node 2
+         
+         //order is undefined
+         
+         cons2.close();
+         
+         cons1 = sess1.createConsumer(queue[1]);
+         
+         cons2 = sess2.createConsumer(queue[2]);
+         
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+            tm = sess0.createTextMessage("message4-" + i);
+
+            prod0.send(tm);
+         }
+         
+         msgs = new HashSet();
+         
+         int count = 0;
+         
+         do
+         {
+            tm = (TextMessage)cons1.receive(1000);
+            
+            if (tm != null)
+            {            
+	            log.info("*** got message " + tm.getText());
+	            
+	            msgs.add(tm.getText());
+	            
+	            count++;
+            }
+         }
+         while (tm != null);
+         
+         do
+         {
+            tm = (TextMessage)cons2.receive(1000);
+            
+            if (tm != null)
+            {            
+	            log.info("*** got message " + tm.getText());
+	            
+	
+	            msgs.add(tm.getText());
+	            
+	            count++;
+            }
+         } 
+         while (tm != null);
+         
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+         	assertTrue(msgs.contains("message4-" + i));
+         }
+         
+         assertEquals(NUM_MESSAGES, count);
+         
+         //as above but start consumers AFTER sending
+         
+         cons1.close();
+         
+         cons2.close();
+         
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+            tm = sess0.createTextMessage("message4-" + i);
+
+            prod0.send(tm);
+         }
+         
+         cons1 = sess1.createConsumer(queue[1]);
+         
+         cons2 = sess2.createConsumer(queue[2]);
+         
+         
+         msgs = new HashSet();
+         
+         count = 0;
+         
+         do
+         {
+            tm = (TextMessage)cons1.receive(1000);
+            
+            if (tm != null)
+            {            
+	            log.info("*** got message " + tm.getText());
+	            
+	            msgs.add(tm.getText());
+	            
+	            count++;
+            }
+         }
+         while (tm != null);
+         
+         do
+         {
+            tm = (TextMessage)cons2.receive(1000);
+            
+            if (tm != null)
+            {
+	            
+	            log.info("*** got message " + tm.getText());
+	            
+	            msgs.add(tm.getText());
+	            
+	            count++;
+            }
+         } 
+         while (tm != null);
+         
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+         	assertTrue(msgs.contains("message4-" + i));
+         }
+         
+         assertEquals(NUM_MESSAGES, count);         
+         
+         
+         // Now send message on node 0, consume on node2, then cancel, consume on node1, cancel, consume on node 0
+         
+         cons1.close();
+         
+         cons2.close();
+         
+         sess2.close();
+         
+         sess2 = conn2.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+         
+         cons2 = sess2.createConsumer(queue[2]);
+         
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+            tm = sess0.createTextMessage("message5-" + i);
+
+            prod0.send(tm);
+         }
+         
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+            tm = (TextMessage)cons2.receive(1000);
+            
+            log.info("*** got message " + tm.getText());
+            
+            assertNotNull(tm);
+               
+            assertEquals("message5-" + i, tm.getText());
+         } 
+         
+         sess2.close(); // messages should go back on queue
+         
+         //Now try on node 1
+         
+         sess1.close();
+         
+         sess1 = conn1.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+         
+         cons1 = sess1.createConsumer(queue[1]);
+         
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+            tm = (TextMessage)cons1.receive(1000);
+            
+            log.info("*** got message " + tm.getText());
+            
+            assertNotNull(tm);
+               
+            assertEquals("message5-" + i, tm.getText());
+         } 
+         
+         sess1.close(); // messages should go back on queue
+         
+         //Now try on node 0
+         
+         cons0 = sess0.createConsumer(queue[0]);
+         
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+            tm = (TextMessage)cons0.receive(1000);
+            
+            log.info("*** got message " + tm.getText());
+            
+            assertNotNull(tm);
+               
+            assertEquals("message5-" + i, tm.getText());
+         }
+                  
+                  
       }
       finally
       {
+         if (conn0 != null)
+         {
+            conn0.close();
+         }
+
          if (conn1 != null)
          {
             conn1.close();
@@ -282,11 +613,6 @@
          {
             conn2.close();
          }
-
-         if (conn3 != null)
-         {
-            conn3.close();
-         }
       }
    }
 
@@ -298,40 +624,38 @@
     */
    private void clusteredTopicNonDurable(boolean persistent) throws Exception
    {
+      Connection conn0 = null;
       Connection conn1 = null;
       Connection conn2 = null;
-      Connection conn3 = null;
       try
       {
          //This will create 3 different connection on 3 different nodes, since
          //the cf is clustered
+         conn0 = cf.createConnection();
          conn1 = cf.createConnection();
          conn2 = cf.createConnection();
-         conn3 = cf.createConnection();
          
          log.info("Created connections");
          
-         checkConnectionsDifferentServers(new Connection[] {conn1, conn2, conn3});
+         checkConnectionsDifferentServers(new Connection[] {conn0, conn1, conn2});
 
+         Session sess0 = conn0.createSession(false, Session.AUTO_ACKNOWLEDGE);
          Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
          Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         Session sess3 = conn3.createSession(false, Session.AUTO_ACKNOWLEDGE);
 
-         MessageConsumer cons1 = sess1.createConsumer(topic[0]);
-         MessageConsumer cons2 = sess2.createConsumer(topic[1]);
-         MessageConsumer cons3 = sess3.createConsumer(topic[2]);
+         MessageConsumer cons0 = sess0.createConsumer(topic[0]);
+         MessageConsumer cons1 = sess1.createConsumer(topic[1]);
+         MessageConsumer cons2 = sess2.createConsumer(topic[2]);
+         MessageConsumer cons3 = sess0.createConsumer(topic[0]);
+         MessageConsumer cons4 = sess1.createConsumer(topic[1]);
 
-         MessageConsumer cons4 = sess1.createConsumer(topic[0]);
-
-         MessageConsumer cons5 = sess2.createConsumer(topic[1]);
-
+         conn0.start();
          conn1.start();
          conn2.start();
-         conn3.start();
 
          // Send at node 0
 
-         MessageProducer prod = sess1.createProducer(topic[0]);
+         MessageProducer prod = sess0.createProducer(topic[0]);
 
          prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
 
@@ -339,58 +663,83 @@
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
-            TextMessage tm = sess1.createTextMessage("message" + i);
+            TextMessage tm = sess0.createTextMessage("message" + i);
 
             prod.send(tm);
          }
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
-            TextMessage tm = (TextMessage)cons1.receive(1000);
+            TextMessage tm = (TextMessage)cons0.receive(1000);
 
             assertNotNull(tm);
 
             assertEquals("message" + i, tm.getText());
          }
+         
+         Message msg = cons0.receive(1000);
+         
+         assertNull(msg);
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
-            TextMessage tm = (TextMessage)cons2.receive(1000);
+            TextMessage tm = (TextMessage)cons1.receive(1000);
 
             assertNotNull(tm);
 
             assertEquals("message" + i, tm.getText());
          }
+         
+         msg = cons1.receive(1000);
+         
+         assertNull(msg);
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
-            TextMessage tm = (TextMessage)cons3.receive(1000);
+            TextMessage tm = (TextMessage)cons2.receive(1000);
 
             assertNotNull(tm);
 
             assertEquals("message" + i, tm.getText());
          }
+         
+         msg = cons2.receive(1000);
+         
+         assertNull(msg);
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
-            TextMessage tm = (TextMessage)cons4.receive(1000);
+            TextMessage tm = (TextMessage)cons3.receive(1000);
 
             assertNotNull(tm);
 
             assertEquals("message" + i, tm.getText());
          }
+         
+         msg = cons3.receive(1000);
+         
+         assertNull(msg);
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
-            TextMessage tm = (TextMessage)cons5.receive(1000);
+            TextMessage tm = (TextMessage)cons4.receive(1000);
 
             assertNotNull(tm);
 
             assertEquals("message" + i, tm.getText());
          }
+         
+         msg = cons4.receive(1000);
+         
+         assertNull(msg);
       }
       finally
       {
+         if (conn0 != null)
+         {
+            conn0.close();
+         }
+
          if (conn1 != null)
          {
             conn1.close();
@@ -400,11 +749,6 @@
          {
             conn2.close();
          }
-
-         if (conn3 != null)
-         {
-            conn3.close();
-         }
       }
    }
 
@@ -415,41 +759,39 @@
     */
    private void clusteredTopicNonDurableWithSelectors(boolean persistent) throws Exception
    {
+      Connection conn0 = null;
       Connection conn1 = null;
       Connection conn2 = null;
-      Connection conn3 = null;
 
       try
       {
          //This will create 3 different connection on 3 different nodes, since
          //the cf is clustered
+         conn0 = cf.createConnection();
          conn1 = cf.createConnection();
          conn2 = cf.createConnection();
-         conn3 = cf.createConnection();
          
          log.info("Created connections");
          
-         checkConnectionsDifferentServers(new Connection[] {conn1, conn2, conn3});
+         checkConnectionsDifferentServers(new Connection[] {conn0, conn1, conn2});
 
+         Session sess0 = conn0.createSession(false, Session.AUTO_ACKNOWLEDGE);
          Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
          Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         Session sess3 = conn3.createSession(false, Session.AUTO_ACKNOWLEDGE);
 
-         MessageConsumer cons1 = sess1.createConsumer(topic[0]);
-         MessageConsumer cons2 = sess2.createConsumer(topic[1]);
-         MessageConsumer cons3 = sess3.createConsumer(topic[2]);
+         MessageConsumer cons0 = sess0.createConsumer(topic[0]);
+         MessageConsumer cons1 = sess1.createConsumer(topic[1]);
+         MessageConsumer cons2 = sess2.createConsumer(topic[2]);
+         MessageConsumer cons3 = sess0.createConsumer(topic[0], "COLOUR='red'");
+         MessageConsumer cons4 = sess1.createConsumer(topic[1], "COLOUR='blue'");
 
-         MessageConsumer cons4 = sess1.createConsumer(topic[0], "COLOUR='red'");
-
-         MessageConsumer cons5 = sess2.createConsumer(topic[1], "COLOUR='blue'");
-
+         conn0.start();
          conn1.start();
          conn2.start();
-         conn3.start();
 
          // Send at node 0
 
-         MessageProducer prod = sess1.createProducer(topic[0]);
+         MessageProducer prod = sess0.createProducer(topic[0]);
 
          prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
 
@@ -457,7 +799,7 @@
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
-            TextMessage tm = sess1.createTextMessage("message" + i);
+            TextMessage tm = sess0.createTextMessage("message" + i);
 
             int c = i % 3;
             if (c == 0)
@@ -474,30 +816,42 @@
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
-            TextMessage tm = (TextMessage)cons1.receive(1000);
+            TextMessage tm = (TextMessage)cons0.receive(1000);
 
             assertNotNull(tm);
 
             assertEquals("message" + i, tm.getText());
          }
+         
+         Message msg = cons0.receive(1000);
+         
+         assertNull(msg);
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
-            TextMessage tm = (TextMessage)cons2.receive(1000);
+            TextMessage tm = (TextMessage)cons1.receive(1000);
 
             assertNotNull(tm);
 
             assertEquals("message" + i, tm.getText());
          }
+         
+         msg = cons1.receive(1000);
+         
+         assertNull(msg);
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
-            TextMessage tm = (TextMessage)cons3.receive(1000);
+            TextMessage tm = (TextMessage)cons2.receive(1000);
 
             assertNotNull(tm);
 
             assertEquals("message" + i, tm.getText());
          }
+         
+         msg = cons2.receive(1000);
+         
+         assertNull(msg);
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
@@ -505,13 +859,17 @@
 
             if (c == 0)
             {
-               TextMessage tm = (TextMessage)cons4.receive(1000);
+               TextMessage tm = (TextMessage)cons3.receive(1000);
 
                assertNotNull(tm);
 
                assertEquals("message" + i, tm.getText());
             }
          }
+         
+         msg = cons3.receive(1000);
+         
+         assertNull(msg);
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
@@ -519,16 +877,25 @@
 
             if (c == 1)
             {
-               TextMessage tm = (TextMessage)cons5.receive(1000);
+               TextMessage tm = (TextMessage)cons4.receive(1000);
 
                assertNotNull(tm);
 
                assertEquals("message" + i, tm.getText());
             }
          }
+         
+         msg = cons4.receive(1000);
+         
+         assertNull(msg);
       }
       finally
       {
+         if (conn0 != null)
+         {
+            conn0.close();
+         }
+
          if (conn1 != null)
          {
             conn1.close();
@@ -538,11 +905,6 @@
          {
             conn2.close();
          }
-
-         if (conn3 != null)
-         {
-            conn3.close();
-         }
       }
    }
 
@@ -600,16 +962,33 @@
             sess1.unsubscribe("epsilon");
          }
          catch (Exception ignore) {}
+         
+         log.info("creating subs");
 
          MessageConsumer alpha = sess0.createDurableSubscriber(topic[0], "alpha");
+         
+         log.info("created 0");
+         
          MessageConsumer beta = sess1.createDurableSubscriber(topic[1], "beta");
+         
+         log.info("created 1");
+         
          MessageConsumer gamma = sess2.createDurableSubscriber(topic[2], "gamma");
+         
+         log.info("created 2");
          MessageConsumer delta = sess0.createDurableSubscriber(topic[0], "delta");
+         
+         log.info("created 3");
+         
          MessageConsumer epsilon = sess1.createDurableSubscriber(topic[1], "epsilon");
+         
+         log.info("created 4");
 
          conn0.start();
          conn1.start();
          conn2.start();
+         
+         log.info("started");
 
          // Send at node 0
 
@@ -625,6 +1004,8 @@
          {
             prod.send(sess0.createTextMessage("message" + i));
          }
+         
+         log.info("Sent messages");
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
@@ -632,6 +1013,11 @@
             assertNotNull(tm);
             assertEquals("message" + i, tm.getText());
          }
+         
+         log.info("got 1");
+         
+         Message msg = alpha.receive(1000);
+         assertNull(msg);         
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
@@ -639,6 +1025,11 @@
             assertNotNull(tm);
             assertEquals("message" + i, tm.getText());
          }
+         
+         log.info("got 2");
+         
+         msg = beta.receive(1000);
+         assertNull(msg);
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
@@ -646,6 +1037,11 @@
             assertNotNull(tm);
             assertEquals("message" + i, tm.getText());
          }
+         
+         log.info("got 3");
+         
+         msg = gamma.receive(1000);
+         assertNull(msg);
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
@@ -653,6 +1049,11 @@
             assertNotNull(tm);
             assertEquals("message" + i, tm.getText());
          }
+         
+         log.info("got 4");
+         
+         msg = delta.receive(1000);
+         assertNull(msg);
 
          for (int i = 0; i < NUM_MESSAGES; i++)
          {
@@ -660,18 +1061,27 @@
             assertNotNull(tm);
             assertEquals("message" + i, tm.getText());
          }
+         
+         log.info("got 5");
+         
+         msg = epsilon.receive(1000);
+         assertNull(msg);
 
          alpha.close();
          beta.close();
          gamma.close();
          delta.close();
          epsilon.close();
+         
+         log.info("got 6");
 
          sess0.unsubscribe("alpha");
          sess1.unsubscribe("beta");
          sess2.unsubscribe("gamma");
          sess0.unsubscribe("delta");
          sess1.unsubscribe("epsilon");
+         
+         log.info("got 7");
 
       }
       finally

Deleted: trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -1,163 +0,0 @@
-/**
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.test.messaging.jms.clustering;
-
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.DeliveryMode;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import javax.management.ObjectName;
-import javax.naming.InitialContext;
-
-import org.jboss.jms.client.JBossConnection;
-import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.test.messaging.tools.ServerManagement;
-import org.jboss.test.messaging.tools.jmx.ServiceAttributeOverrides;
-
-/**
- * Extending MessagingTestCase and not ClusteringTestBase because I want to start the messaging
- * servers (the clustered post offices in this case) configured in a particular way (a specific
- * message redistribution policy).
- *
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class DistributedQueueTest extends MessagingTestCase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-
-   // Attributes ----------------------------------------------------
-
-   // Constructors --------------------------------------------------
-
-   public DistributedQueueTest(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-
-   public void testMessageRedistributionAmongNodes() throws Exception
-   {
-      // start servers with redistribution policies that actually do something
-      ServiceAttributeOverrides attrOverrides = new ServiceAttributeOverrides();
-
-      ObjectName postOfficeObjectName = new ObjectName("jboss.messaging:service=PostOffice");
-
-      attrOverrides.
-         put(postOfficeObjectName, "MessagePullPolicy",
-             "org.jboss.messaging.core.plugin.postoffice.cluster.DefaultMessagePullPolicy");
-
-      attrOverrides.put(postOfficeObjectName, "StatsSendPeriod", new Long(1000));
-
-      ServerManagement.start(0, "all", attrOverrides, true);
-      ServerManagement.start(1, "all", attrOverrides, false);
-
-      ServerManagement.deployQueue("testDistributedQueue", 0);
-      ServerManagement.deployQueue("testDistributedQueue", 1);
-
-      InitialContext ic0 = null;
-      InitialContext ic1 = null;
-      Connection conn = null;
-
-      try
-      {
-         ic0 = new InitialContext(ServerManagement.getJNDIEnvironment(0));
-         ic1 = new InitialContext(ServerManagement.getJNDIEnvironment(1));
-
-         ConnectionFactory cf = (ConnectionFactory)ic0.lookup("/ClusteredConnectionFactory");
-         Queue queue0 = (Queue)ic0.lookup("/queue/testDistributedQueue");
-         Queue queue1 = (Queue)ic1.lookup("/queue/testDistributedQueue");
-
-         conn = cf.createConnection();
-
-         // make sure we're connecting to node 0
-
-         assertEquals(0, ((JBossConnection)conn).getServerID());
-
-         // send a message
-
-         Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         MessageProducer p = s.createProducer(queue0);
-         p.setDeliveryMode(DeliveryMode.PERSISTENT);
-         p.send(s.createTextMessage("blip"));
-
-         conn.close();
-
-         // create a connection to a different node
-
-         conn = cf.createConnection();
-
-         // make sure we're connecting to node 1
-
-         assertEquals(1, ((JBossConnection)conn).getServerID());
-
-         s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         MessageConsumer c = s.createConsumer(queue1);
-         conn.start();
-
-         // we must receive the message
-
-         TextMessage tm = (TextMessage)c.receive(10000);
-         assertNotNull(tm);
-         assertEquals("blip", tm.getText());
-
-      }
-      finally
-      {
-         if (conn != null)
-         {
-            conn.close();
-         }
-
-         if (ic0 != null)
-         {
-            ic0.close();
-         }
-
-         if (ic1 != null)
-         {
-            ic1.close();
-         }
-
-         ServerManagement.undeployQueue("testDistributedQueue", 0);
-         ServerManagement.undeployQueue("testDistributedQueue", 1);
-
-         ServerManagement.stop(1);
-         ServerManagement.stop(0);
-      }
-   }
-
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-
-   protected void setUp() throws Exception
-   {
-      super.setUp();
-
-      log.debug("setup done");
-   }
-
-   protected void tearDown() throws Exception
-   {
-      super.tearDown();
-   }
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-
-}

Modified: trunk/tests/src/org/jboss/test/messaging/jms/clustering/GroupManagementTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/clustering/GroupManagementTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/clustering/GroupManagementTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -58,6 +58,8 @@
       try
       {
          ServerManagement.start(0, "all");
+         
+         log.info("Started server 0");
 
          ServerManagement.addNotificationListener(0, postOfficeObjectName, listener);
 

Modified: trunk/tests/src/org/jboss/test/messaging/jms/clustering/RequestResponseWithPullTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/clustering/RequestResponseWithPullTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/clustering/RequestResponseWithPullTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -83,8 +83,6 @@
          put(postOfficeObjectName, "MessagePullPolicy",
              "org.jboss.messaging.core.plugin.postoffice.cluster.DefaultMessagePullPolicy");
 
-      attrOverrides.put(postOfficeObjectName, "StatsSendPeriod", new Long(1000));
-
       ServerManagement.start(0, "all", attrOverrides, true);
       ServerManagement.start(1, "all", attrOverrides, false);
 

Modified: trunk/tests/src/org/jboss/test/messaging/jms/clustering/base/ClusteringTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/clustering/base/ClusteringTestBase.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/clustering/base/ClusteringTestBase.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -119,11 +119,12 @@
 
    protected void tearDown() throws Exception
    {
-
+   	log.info("tearing down");
       for(int i = 0; i < nodeCount; i++)
       {
          if (ServerManagement.isStarted(i))
          {
+         	log.info("stopping server " + i);
             ServerManagement.log(ServerManagement.INFO, "Undeploying Server " + i, i);
             ServerManagement.undeployQueue("testDistributedQueue", i);
             ServerManagement.undeployTopic("testDistributedTopic", i);

Modified: trunk/tests/src/org/jboss/test/messaging/jms/persistence/BytesMessagePersistenceManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/persistence/BytesMessagePersistenceManagerTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/persistence/BytesMessagePersistenceManagerTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -24,7 +24,7 @@
 import java.util.HashMap;
 
 import org.jboss.jms.message.JBossBytesMessage;
-import org.jboss.messaging.core.message.Message;
+import org.jboss.messaging.core.contract.Message;
 
 
 /**

Modified: trunk/tests/src/org/jboss/test/messaging/jms/persistence/MapMessagePersistenceManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/persistence/MapMessagePersistenceManagerTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/persistence/MapMessagePersistenceManagerTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -26,7 +26,7 @@
 import java.util.Map;
 
 import org.jboss.jms.message.JBossMapMessage;
-import org.jboss.messaging.core.message.Message;
+import org.jboss.messaging.core.contract.Message;
 
 
 /**

Modified: trunk/tests/src/org/jboss/test/messaging/jms/persistence/MessagePersistenceManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/persistence/MessagePersistenceManagerTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/persistence/MessagePersistenceManagerTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -29,9 +29,9 @@
 import org.jboss.jms.destination.JBossQueue;
 import org.jboss.jms.destination.JBossTopic;
 import org.jboss.jms.message.JBossMessage;
-import org.jboss.messaging.core.message.Message;
-import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
-import org.jboss.test.messaging.core.plugin.JDBCPersistenceManagerTest;
+import org.jboss.messaging.core.contract.Message;
+import org.jboss.messaging.core.impl.JDBCPersistenceManager;
+import org.jboss.test.messaging.core.JDBCPersistenceManagerTest;
 import org.jboss.test.messaging.tools.ServerManagement;
 import org.jboss.util.id.GUID;
 

Modified: trunk/tests/src/org/jboss/test/messaging/jms/persistence/ObjectMessagePersistenceManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/persistence/ObjectMessagePersistenceManagerTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/persistence/ObjectMessagePersistenceManagerTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -24,7 +24,7 @@
 import java.util.HashMap;
 
 import org.jboss.jms.message.JBossObjectMessage;
-import org.jboss.messaging.core.message.Message;
+import org.jboss.messaging.core.contract.Message;
 
 
 /**

Modified: trunk/tests/src/org/jboss/test/messaging/jms/persistence/StreamMessagePersistenceManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/persistence/StreamMessagePersistenceManagerTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/persistence/StreamMessagePersistenceManagerTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -25,7 +25,7 @@
 import java.util.HashMap;
 
 import org.jboss.jms.message.JBossStreamMessage;
-import org.jboss.messaging.core.message.Message;
+import org.jboss.messaging.core.contract.Message;
 
 
 /**

Modified: trunk/tests/src/org/jboss/test/messaging/jms/persistence/TextMessagePersistenceManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/persistence/TextMessagePersistenceManagerTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/persistence/TextMessagePersistenceManagerTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -24,7 +24,7 @@
 import java.util.HashMap;
 
 import org.jboss.jms.message.JBossTextMessage;
-import org.jboss.messaging.core.message.Message;
+import org.jboss.messaging.core.contract.Message;
 
 
 /**

Modified: trunk/tests/src/org/jboss/test/messaging/jms/server/ServerPeerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/server/ServerPeerTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/server/ServerPeerTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -376,15 +376,15 @@
          
          assertEquals(-1, i.intValue());
          
-         Long l = (Long)ServerManagement.getAttribute(ServerManagement.getServerPeerObjectName(), "QueueStatsSamplePeriod");
+         Long l = (Long)ServerManagement.getAttribute(ServerManagement.getServerPeerObjectName(), "MessageCounterSamplePeriod");
          
          assertNotNull(l);
          
          assertEquals(5000, l.longValue()); //default value
          
-         ServerManagement.setAttribute(ServerManagement.getServerPeerObjectName(), "QueueStatsSamplePeriod", String.valueOf(1000));
+         ServerManagement.setAttribute(ServerManagement.getServerPeerObjectName(), "MessageCounterSamplePeriod", String.valueOf(1000));
          
-         l = (Long)ServerManagement.getAttribute(ServerManagement.getServerPeerObjectName(), "QueueStatsSamplePeriod");
+         l = (Long)ServerManagement.getAttribute(ServerManagement.getServerPeerObjectName(), "MessageCounterSamplePeriod");
          
          assertNotNull(l);
          

Modified: trunk/tests/src/org/jboss/test/messaging/jms/server/destination/QueueManagementTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/server/destination/QueueManagementTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/server/destination/QueueManagementTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -783,7 +783,7 @@
       InitialContext ic = new InitialContext(ServerManagement.getJNDIEnvironment());
       ConnectionFactory cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
       
-      ServerManagement.setAttribute(ServerManagement.getServerPeerObjectName(), "QueueStatsSamplePeriod", String.valueOf(1000));
+      ServerManagement.setAttribute(ServerManagement.getServerPeerObjectName(), "MessageCounterSamplePeriod", String.valueOf(1000));
       
       ServerManagement.invoke(ServerManagement.getServerPeerObjectName(), "enableMessageCounters", null, null);
       

Modified: trunk/tests/src/org/jboss/test/messaging/jms/server/destination/TopicManagementTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/server/destination/TopicManagementTest.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/server/destination/TopicManagementTest.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -110,10 +110,10 @@
    
          Connection conn = cf.createConnection();
          
+         conn.setClientID("wibble765");         
+         
          conn.start();
-         
-         conn.setClientID("wibble765");
-         
+             
          Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
          
          MessageConsumer cons = sess.createDurableSubscriber(topic, "subxyz");
@@ -236,6 +236,13 @@
          //Need to pause since delivery may still be in progress
          Thread.sleep(2000);
          
+         count = ((Integer)ServerManagement.getAttribute(destObjectName, "AllMessageCount")).intValue();
+         
+         //Note we only keep track of deliveries for DURABLE subs so count should be 1
+         //no durable are effectively acked immediately
+         
+         assertEquals(1, count);
+         
          //This should fail since you cannot remove messages if there are deliveries in progress
          try
          {
@@ -249,7 +256,7 @@
    
          count = ((Integer)ServerManagement.getAttribute(destObjectName, "AllMessageCount")).intValue();
          
-         assertEquals(2, count);
+         assertEquals(1, count);
                   
          // Now close the connection
          conn.close();

Modified: trunk/tests/src/org/jboss/test/messaging/jms/stress/base/StressTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/stress/base/StressTestBase.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/jms/stress/base/StressTestBase.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -26,7 +26,7 @@
 import javax.jms.Topic;
 import javax.naming.InitialContext;
 
-import org.jboss.messaging.core.plugin.LockMap;
+import org.jboss.messaging.util.LockMap;
 import org.jboss.test.messaging.MessagingTestCase;
 import org.jboss.test.messaging.jms.stress.Runner;
 import org.jboss.test.messaging.tools.ServerManagement;

Modified: trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -39,8 +39,8 @@
 
 import org.jboss.jms.server.DestinationManager;
 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.contract.MessageStore;
+import org.jboss.messaging.core.contract.PersistenceManager;
 import org.jboss.remoting.ServerInvocationHandler;
 import org.jboss.test.messaging.tools.jmx.ServiceAttributeOverrides;
 import org.jboss.test.messaging.tools.jmx.rmi.LocalTestServer;

Modified: trunk/tests/src/org/jboss/test/messaging/tools/jmx/ServiceContainer.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/tools/jmx/ServiceContainer.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/tools/jmx/ServiceContainer.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -624,14 +624,7 @@
    {
       String databaseName = getDatabaseName();
 
-      if (clustered && !getDatabaseName().equals("hsqldb"))
-      {
-         return "server/default/deploy/clustered-" + databaseName + "-persistence-service.xml";
-      }
-      else
-      {
-         return "server/default/deploy/" + databaseName + "-persistence-service.xml";
-      }
+      return "server/default/deploy/" + databaseName + "-persistence-service.xml";      
    }
    
    public Properties getPersistenceManagerSQLProperties() throws Exception
@@ -662,32 +655,6 @@
 
    public Properties getPostOfficeSQLProperties() throws Exception
    {
-      String persistenceConfigFile = getPersistenceConfigFile(false);
-      log.info("Peristence config file: .. " + persistenceConfigFile);
-
-      MBeanConfigurationElement postOfficeConfig =
-         ServiceConfigHelper.loadServiceConfiguration(persistenceConfigFile, "PostOffice");
-
-      String props = postOfficeConfig.getAttributeValue("SqlProperties");
-
-      if (props != null)
-      {
-         ByteArrayInputStream is = new ByteArrayInputStream(props.getBytes());
-
-         Properties sqlProperties = new Properties();
-
-         sqlProperties.load(is);
-
-         return sqlProperties;
-      }
-      else
-      {
-         return null;
-      }
-   }
-
-   public Properties getClusteredPostOfficeSQLProperties() throws Exception
-   {
       String persistenceConfigFile = getPersistenceConfigFile(true);
       log.info("Persistence config file: .... " + persistenceConfigFile);
 
@@ -1633,6 +1600,19 @@
          invoke(on, "start", new Object[0], new String[0]);
          connFactoryObjectNames.add(on);
       }
+      
+      connFactoryElements = cfdd.query("service", "ClusterPullConnectionFactory");
+
+      for (Iterator i = connFactoryElements.iterator(); i.hasNext();)
+      {
+         MBeanConfigurationElement connFactoryElement = (MBeanConfigurationElement) i.next();
+         ObjectName on = registerAndConfigureService(connFactoryElement);
+         overrideAttributes(on, attrOverrides);
+         // dependencies have been automatically injected already
+         invoke(on, "create", new Object[0], new String[0]);
+         invoke(on, "start", new Object[0], new String[0]);
+         connFactoryObjectNames.add(on);
+      }
    }
 
 

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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/LocalTestServer.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -38,8 +38,8 @@
 import org.jboss.jms.server.DestinationManager;
 import org.jboss.jms.server.ServerPeer;
 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.contract.MessageStore;
+import org.jboss.messaging.core.contract.PersistenceManager;
 import org.jboss.messaging.util.XMLUtil;
 import org.jboss.remoting.ServerInvocationHandler;
 import org.jboss.test.messaging.tools.ServerManagement;
@@ -350,7 +350,11 @@
          MBeanConfigurationElement postOfficeConfig =
             ServiceConfigHelper.getServiceConfiguration(pdd, "PostOffice");
 
-         postOfficeObjectName = sc.registerAndConfigureService(postOfficeConfig);
+         postOfficeObjectName = sc.registerAndConfigureService(postOfficeConfig);         
+         sc.setAttribute(postOfficeObjectName, "Clustered", clustered ? "true" : "false"); 
+         
+         log.info("************* SET CLUSTERED ATTRIBUTE TO " + clustered);
+         
          overrideAttributes(postOfficeObjectName, attrOverrides);
          sc.invoke(postOfficeObjectName, "create", new Object[0], new String[0]);
          sc.invoke(postOfficeObjectName, "start", new Object[0], new String[0]);

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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/RMITestServer.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -37,8 +37,8 @@
 import org.jboss.jms.server.DestinationManager;
 import org.jboss.jms.server.ServerPeer;
 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.contract.MessageStore;
+import org.jboss.messaging.core.contract.PersistenceManager;
 import org.jboss.remoting.ServerInvocationHandler;
 import org.jboss.test.messaging.tools.jmx.ServiceAttributeOverrides;
 

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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/RemoteTestServer.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -22,8 +22,8 @@
 package org.jboss.test.messaging.tools.jmx.rmi;
 
 import org.jboss.jms.server.DestinationManager;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.PersistenceManager;
 
 /**
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>

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	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/Server.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -29,11 +29,10 @@
 import javax.management.ObjectName;
 import javax.transaction.UserTransaction;
 
-import org.jboss.jms.jndi.JMSProviderAdapter;
 import org.jboss.jms.server.DestinationManager;
 import org.jboss.jms.server.ServerPeer;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
+import org.jboss.messaging.core.contract.MessageStore;
+import org.jboss.messaging.core.contract.PersistenceManager;
 import org.jboss.remoting.ServerInvocationHandler;
 import org.jboss.test.messaging.tools.jmx.ServiceAttributeOverrides;
 

Modified: trunk/tests/src/org/jboss/test/messaging/util/CoreMessageFactory.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/util/CoreMessageFactory.java	2007-06-22 21:05:39 UTC (rev 2795)
+++ trunk/tests/src/org/jboss/test/messaging/util/CoreMessageFactory.java	2007-06-25 22:24:41 UTC (rev 2796)
@@ -24,7 +24,7 @@
 import java.io.Serializable;
 import java.util.Map;
 
-import org.jboss.messaging.core.message.CoreMessage;
+import org.jboss.messaging.core.impl.message.CoreMessage;
 
 /**
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>




More information about the jboss-cvs-commits mailing list