[jboss-cvs] JBoss Messaging SVN: r4904 - in trunk: native/bin and 44 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Sep 3 22:35:14 EDT 2008


Author: clebert.suconic at jboss.com
Date: 2008-09-03 22:35:13 -0400 (Wed, 03 Sep 2008)
New Revision: 4904

Added:
   trunk/src/main/org/jboss/messaging/core/asyncio/BufferCallback.java
   trunk/src/main/org/jboss/messaging/core/journal/BufferCallback.java
   trunk/src/main/org/jboss/messaging/core/paging/LastPageRecord.java
   trunk/src/main/org/jboss/messaging/core/paging/Page.java
   trunk/src/main/org/jboss/messaging/core/paging/PageMessage.java
   trunk/src/main/org/jboss/messaging/core/paging/PageTransactionInfo.java
   trunk/src/main/org/jboss/messaging/core/paging/PagingStore.java
   trunk/src/main/org/jboss/messaging/core/paging/PagingStoreFactory.java
   trunk/src/main/org/jboss/messaging/core/paging/impl/
   trunk/src/main/org/jboss/messaging/core/paging/impl/LastPageRecordImpl.java
   trunk/src/main/org/jboss/messaging/core/paging/impl/PageImpl.java
   trunk/src/main/org/jboss/messaging/core/paging/impl/PageMessageImpl.java
   trunk/src/main/org/jboss/messaging/core/paging/impl/PageTransactionInfoImpl.java
   trunk/src/main/org/jboss/messaging/core/paging/impl/PagingManagerFactoryNIO.java
   trunk/src/main/org/jboss/messaging/core/paging/impl/PagingManagerImpl.java
   trunk/src/main/org/jboss/messaging/core/paging/impl/PagingStoreImpl.java
   trunk/src/main/org/jboss/messaging/core/paging/impl/TestSupportPageStore.java
   trunk/tests/src/org/jboss/messaging/tests/integration/paging/
   trunk/tests/src/org/jboss/messaging/tests/integration/paging/PagingIntegrationTest.java
   trunk/tests/src/org/jboss/messaging/tests/integration/paging/PagingManagerIntegrationTest.java
   trunk/tests/src/org/jboss/messaging/tests/integration/paging/PagingStoreIntegrationTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/CleanBufferTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/
   trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/
   trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PageImplTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PageImplTestBase.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PageManagerImplTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PageTransactionImplTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PagingStoreImplTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PagingStoreTestBase.java
Modified:
   trunk/native/bin/libJBMLibAIO64.so
   trunk/native/configure.ac
   trunk/native/src/JNICallbackAdapter.cpp
   trunk/native/src/LibAIOController.cpp
   trunk/native/src/Version.h
   trunk/native/src/org_jboss_messaging_core_asyncio_impl_AsynchronousFileImpl.h
   trunk/src/config/jbm-configuration.xml
   trunk/src/config/queues.xml
   trunk/src/main/org/jboss/messaging/core/asyncio/AsynchronousFile.java
   trunk/src/main/org/jboss/messaging/core/asyncio/impl/AsynchronousFileImpl.java
   trunk/src/main/org/jboss/messaging/core/config/Configuration.java
   trunk/src/main/org/jboss/messaging/core/config/impl/ConfigurationImpl.java
   trunk/src/main/org/jboss/messaging/core/config/impl/FileConfiguration.java
   trunk/src/main/org/jboss/messaging/core/deployers/impl/QueueSettingsDeployer.java
   trunk/src/main/org/jboss/messaging/core/journal/SequentialFile.java
   trunk/src/main/org/jboss/messaging/core/journal/SequentialFileFactory.java
   trunk/src/main/org/jboss/messaging/core/journal/impl/AIOSequentialFile.java
   trunk/src/main/org/jboss/messaging/core/journal/impl/AIOSequentialFileFactory.java
   trunk/src/main/org/jboss/messaging/core/journal/impl/JournalImpl.java
   trunk/src/main/org/jboss/messaging/core/journal/impl/NIOSequentialFile.java
   trunk/src/main/org/jboss/messaging/core/journal/impl/NIOSequentialFileFactory.java
   trunk/src/main/org/jboss/messaging/core/management/QueueControlMBean.java
   trunk/src/main/org/jboss/messaging/core/management/impl/QueueControl.java
   trunk/src/main/org/jboss/messaging/core/paging/PagingManager.java
   trunk/src/main/org/jboss/messaging/core/persistence/StorageManager.java
   trunk/src/main/org/jboss/messaging/core/persistence/impl/journal/JournalStorageManager.java
   trunk/src/main/org/jboss/messaging/core/persistence/impl/nullpm/NullStorageManager.java
   trunk/src/main/org/jboss/messaging/core/postoffice/PostOffice.java
   trunk/src/main/org/jboss/messaging/core/postoffice/impl/PostOfficeImpl.java
   trunk/src/main/org/jboss/messaging/core/server/Queue.java
   trunk/src/main/org/jboss/messaging/core/server/ServerMessage.java
   trunk/src/main/org/jboss/messaging/core/server/impl/MessageReferenceImpl.java
   trunk/src/main/org/jboss/messaging/core/server/impl/MessagingServerImpl.java
   trunk/src/main/org/jboss/messaging/core/server/impl/QueueFactoryImpl.java
   trunk/src/main/org/jboss/messaging/core/server/impl/QueueImpl.java
   trunk/src/main/org/jboss/messaging/core/server/impl/ServerMessageImpl.java
   trunk/src/main/org/jboss/messaging/core/server/impl/ServerSessionImpl.java
   trunk/src/main/org/jboss/messaging/core/settings/impl/QueueSettings.java
   trunk/src/main/org/jboss/messaging/core/transaction/impl/TransactionImpl.java
   trunk/src/main/org/jboss/messaging/jms/server/management/impl/JMSQueueControl.java
   trunk/src/main/org/jboss/messaging/jms/server/management/impl/TopicControl.java
   trunk/tests/jms-tests/src/org/jboss/test/messaging/jms/QueueRequestorTest.java
   trunk/tests/src/org/jboss/messaging/tests/performance/journal/JournalImplTestUnit.java
   trunk/tests/src/org/jboss/messaging/tests/performance/persistence/FakePostOffice.java
   trunk/tests/src/org/jboss/messaging/tests/stress/journal/AddAndRemoveStressTest.java
   trunk/tests/src/org/jboss/messaging/tests/stress/journal/remote/RemoteJournalAppender.java
   trunk/tests/src/org/jboss/messaging/tests/timing/core/server/impl/QueueImplTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/AlignedJournalImplTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/EasyMockJournalTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/JournalAsyncTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/JournalImplTestBase.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/JournalImplTestUnit.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/fakes/FakeSequentialFileFactory.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/management/impl/QueueControlTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/PostOfficeImplTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/MessageReferenceImplTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/QueueFactoryImplTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/QueueImplTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/ServerConsumerImplTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/ServerMessageImplTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/ServerSessionImplTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/fakes/FakeQueueFactory.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/settings/impl/QueueSettingsTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/core/transaction/impl/TransactionImplTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/jms/server/management/impl/JMSQueueControlTest.java
   trunk/tests/src/org/jboss/messaging/tests/unit/jms/server/management/impl/TopicControlTest.java
   trunk/tests/src/org/jboss/messaging/tests/util/RandomUtil.java
   trunk/tests/src/org/jboss/messaging/tests/util/UnitTestCase.java
Log:
JBMESSAGING-1314 - Paging implementation and few optimizations on the journal (JBMESSAGING-1342)

Modified: trunk/native/bin/libJBMLibAIO64.so
===================================================================
(Binary files differ)

Modified: trunk/native/configure.ac
===================================================================
--- trunk/native/configure.ac	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/native/configure.ac	2008-09-04 02:35:13 UTC (rev 4904)
@@ -1,7 +1,6 @@
 #                                               -*- Autoconf -*-
 # Process this file with autoconf to produce a configure script.
 
-AC_PREREQ(2.61)
 AC_INIT([jboss-messaging-native], [1.0.Alpha],[clebert.suconic at jboss.org])
 AC_CONFIG_AUX_DIR([build-aux])
 
@@ -23,7 +22,9 @@
 	
 
 gl_COMPILER_FLAGS(-Werror)
-gl_COMPILER_FLAGS(-g)
+#gl_COMPILER_FLAGS(-g) -- enable this for debug
+# Compile it with full optimizations
+gl_COMPILER_FLAGS(-O3) 
 gl_COMPILER_FLAGS(-pedantic)
 gl_COMPILER_FLAGS(-Wall)
 gl_COMPILER_FLAGS(-Wextra)

Modified: trunk/native/src/JNICallbackAdapter.cpp
===================================================================
--- trunk/native/src/JNICallbackAdapter.cpp	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/native/src/JNICallbackAdapter.cpp	2008-09-04 02:35:13 UTC (rev 4904)
@@ -36,7 +36,7 @@
 
 void JNICallbackAdapter::done(THREAD_CONTEXT threadContext)
 {
-	JNI_ENV(threadContext)->CallVoidMethod(fileController, controller->done, callback); 
+	JNI_ENV(threadContext)->CallVoidMethod(fileController, controller->done, callback, bufferReference); 
 	return;
 }
 

Modified: trunk/native/src/LibAIOController.cpp
===================================================================
--- trunk/native/src/LibAIOController.cpp	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/native/src/LibAIOController.cpp	2008-09-04 02:35:13 UTC (rev 4904)
@@ -50,7 +50,7 @@
 		std::string fileName = convertJavaString(env, jstrFileName);
 		
 		AIOController * controller = new AIOController(fileName, (int) maxIO);
-		controller->done = env->GetMethodID(clazz,"callbackDone","(Lorg/jboss/messaging/core/asyncio/AIOCallback;)V");
+		controller->done = env->GetMethodID(clazz,"callbackDone","(Lorg/jboss/messaging/core/asyncio/AIOCallback;Ljava/nio/ByteBuffer;)V");
 		if (!controller->done) return 0;
 		
 		controller->error = env->GetMethodID(clazz, "callbackError", "(Lorg/jboss/messaging/core/asyncio/AIOCallback;ILjava/lang/String;)V");
@@ -105,6 +105,23 @@
 	}
 }
 
+JNIEXPORT void JNICALL Java_org_jboss_messaging_core_asyncio_impl_AsynchronousFileImpl_resetBuffer
+  (JNIEnv *env, jclass, jobject jbuffer, jint size)
+{
+	void * buffer = env->GetDirectBufferAddress(jbuffer);
+	
+	if (buffer == 0)
+	{
+		throwException(env, "java/lang/IllegalStateException", "Invalid Direct Buffer used");
+		return;
+	}
+	
+	memset(buffer, 0, (size_t)size);
+	
+}
+
+
+
 JNIEXPORT void JNICALL Java_org_jboss_messaging_core_asyncio_impl_AsynchronousFileImpl_write
   (JNIEnv *env, jobject objThis, jlong controllerAddress, jlong position, jlong size, jobject jbuffer, jobject callback)
 {
@@ -182,8 +199,7 @@
 		AIOController * controller = (AIOController *) controllerAddress;
 		
 		controller->fileOutput.preAllocate(env, position, blocks, size, fillChar);
-		
-		//controller->fileOutput.preAllocate(env, blocks, size);
+
 	}
 	catch (AIOException& e)
 	{

Modified: trunk/native/src/Version.h
===================================================================
--- trunk/native/src/Version.h	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/native/src/Version.h	2008-09-04 02:35:13 UTC (rev 4904)
@@ -1,5 +1,5 @@
 
 #ifndef _VERSION_NATIVE_AIO
-#define _VERSION_NATIVE_AIO 10
+#define _VERSION_NATIVE_AIO 14
 #endif
 

Modified: trunk/native/src/org_jboss_messaging_core_asyncio_impl_AsynchronousFileImpl.h
===================================================================
--- trunk/native/src/org_jboss_messaging_core_asyncio_impl_AsynchronousFileImpl.h	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/native/src/org_jboss_messaging_core_asyncio_impl_AsynchronousFileImpl.h	2008-09-04 02:35:13 UTC (rev 4904)
@@ -13,6 +13,14 @@
 /* Inaccessible static: EXPECTED_NATIVE_VERSION */
 /*
  * Class:     org_jboss_messaging_core_asyncio_impl_AsynchronousFileImpl
+ * Method:    resetBuffer
+ * Signature: (Ljava/nio/ByteBuffer;I)V
+ */
+JNIEXPORT void JNICALL Java_org_jboss_messaging_core_asyncio_impl_AsynchronousFileImpl_resetBuffer
+  (JNIEnv *, jclass, jobject, jint);
+
+/*
+ * Class:     org_jboss_messaging_core_asyncio_impl_AsynchronousFileImpl
  * Method:    init
  * Signature: (Ljava/lang/String;ILorg/jboss/messaging/core/logging/Logger;)J
  */

Modified: trunk/src/config/jbm-configuration.xml
===================================================================
--- trunk/src/config/jbm-configuration.xml	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/config/jbm-configuration.xml	2008-09-04 02:35:13 UTC (rev 4904)
@@ -106,6 +106,10 @@
 
       <journal-type>ASYNCIO</journal-type>
 
+      <!-- The journal will reuse any buffers where the size < journal-buffer-reuse-size on write operations
+           Set this to -1 to disable this feature -->
+      <journal-buffer-reuse-size>4096</journal-buffer-reuse-size>
+
       <!-- Does the journal sync to disk on each transaction commit, prepare or rollback? -->
       <journal-sync-transactional>true</journal-sync-transactional>
       

Modified: trunk/src/config/queues.xml
===================================================================
--- trunk/src/config/queues.xml	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/config/queues.xml	2008-09-04 02:35:13 UTC (rev 4904)
@@ -93,6 +93,12 @@
       <clustered>false</clustered>
    </queue-settings>
 
+   <queue-settings match="queuejms.MyQueue">
+      <max-size-bytes>104857600</max-size-bytes>
+      <page-size-bytes>10485760</page-size-bytes>
+      <drop-messages-when-full>false</drop-messages-when-full>
+   </queue-settings>
+
    <!--default for catch all-->
    <queue-settings match="*">
       <clustered>false</clustered>

Modified: trunk/src/main/org/jboss/messaging/core/asyncio/AsynchronousFile.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/asyncio/AsynchronousFile.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/asyncio/AsynchronousFile.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -54,6 +54,8 @@
 	
 	ByteBuffer newBuffer(int size);
 	
+	void setBufferCallback(BufferCallback callback);
+	
 	int getBlockSize();
 	
 	String getFileName();

Added: trunk/src/main/org/jboss/messaging/core/asyncio/BufferCallback.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/asyncio/BufferCallback.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/asyncio/BufferCallback.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.asyncio;
+
+import java.nio.ByteBuffer;
+
+/**
+ * 
+ * Used to receive a notification on completed buffers used by the AIO layer.
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public interface BufferCallback
+{
+   void bufferDone(ByteBuffer buffer);
+}

Modified: trunk/src/main/org/jboss/messaging/core/asyncio/impl/AsynchronousFileImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/asyncio/impl/AsynchronousFileImpl.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/asyncio/impl/AsynchronousFileImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -31,6 +31,7 @@
 
 import org.jboss.messaging.core.asyncio.AIOCallback;
 import org.jboss.messaging.core.asyncio.AsynchronousFile;
+import org.jboss.messaging.core.asyncio.BufferCallback;
 import org.jboss.messaging.core.logging.Logger;
 
 
@@ -53,7 +54,7 @@
    
    private static boolean loaded = false;
    
-   private static int EXPECTED_NATIVE_VERSION = 10;
+   private static int EXPECTED_NATIVE_VERSION = 14;
       
    static void addMax(int io)
    {
@@ -84,7 +85,7 @@
       }
       catch (Throwable e)
       {
-         log.trace(name + " -> error loading it", e);
+         log.trace(name + " -> error loading the native library", e);
          return false;
       }
       
@@ -123,10 +124,11 @@
 		
 	private boolean opened = false;
 	private String fileName;
-	private Thread poller;	
+	private volatile Thread poller;	
 	private int maxIO;	
 	private Lock writeLock = new ReentrantReadWriteLock().writeLock();
    private Semaphore writeSemaphore;   
+   private BufferCallback bufferCallback;
 	
 	/**
 	 *  Warning: Beware of the C++ pointer! It will bite you! :-)
@@ -156,7 +158,6 @@
 			this.fileName=fileName;
 			handler = init (fileName, this.maxIO, log);
 			addMax(this.maxIO);
-			startPoller();
 		}
 		finally
 		{
@@ -178,9 +179,13 @@
 	         log.warn("Couldn't acquire lock after 60 seconds on AIO", new Exception ("Warning: Couldn't acquire lock after 60 seconds on AIO"));
 	      }
 	      writeSemaphore = null;
-	      stopPoller(handler);
-	      // We need to make sure we won't call close until Poller is completely done, or we might get beautiful GPFs
-	      poller.join();
+	      if (poller != null)
+	      {
+	         Thread currentPoller = poller;
+   	      stopPoller(handler);
+   	      // We need to make sure we won't call close until Poller is completely done, or we might get beautiful GPFs
+   	      currentPoller.join();
+	      }
 
 	      closeInternal(handler);
 			addMax(maxIO * -1);
@@ -196,6 +201,10 @@
 	public void write(final long position, final long size, final ByteBuffer directByteBuffer, final AIOCallback aioPackage)
 	{
 		checkOpened();
+		if (poller == null)
+		{
+		   startPoller();
+		}
       writeSemaphore.acquireUninterruptibly();
 		try
 		{
@@ -212,6 +221,10 @@
 	public void read(final long position, final long size, final ByteBuffer directByteBuffer, final AIOCallback aioPackage)
 	{
 		checkOpened();
+      if (poller == null)
+      {
+         startPoller();
+      }
       writeSemaphore.acquireUninterruptibly();
 		try
 		{
@@ -257,16 +270,25 @@
       return ByteBuffer.allocateDirect((int)size);
    }
    
+   public void setBufferCallback(BufferCallback callback)
+   {
+      this.bufferCallback = callback;
+   }
+
       
 	// Private
 	// ---------------------------------------------------------------------------------
 	
-	/** The JNI layer will call this method, so we could use it to unlock readWriteLocks held in the java layer */
+   /** The JNI layer will call this method, so we could use it to unlock readWriteLocks held in the java layer */
 	@SuppressWarnings("unused") // Called by the JNI layer.. just ignore the warning
-	private void callbackDone(final AIOCallback callback)
+	private void callbackDone(final AIOCallback callback, final ByteBuffer buffer)
 	{
       writeSemaphore.release();
 		callback.done();
+		if (this.bufferCallback != null)
+		{
+		   this.bufferCallback.bufferDone(buffer);
+		}
 	}
 	
 	@SuppressWarnings("unused") // Called by the JNI layer.. just ignore the warning
@@ -286,18 +308,31 @@
 		internalPollEvents(handler);
 	}
 	
-	private synchronized void startPoller()
+	private void startPoller()
 	{
 		checkOpened();
 		
-		poller = new PollerThread(); 
+		writeLock.lock();
+		
 		try
 		{
-			poller.start();
+   		
+   		if (poller == null)
+   		{
+      		poller = new PollerThread(); 
+      		try
+      		{
+      			poller.start();
+      		}
+      		catch (Exception ex)
+      		{
+      			log.error(ex.getMessage(), ex);
+      		}
+   		}
 		}
-		catch (Exception ex)
+		finally
 		{
-			log.error(ex.getMessage(), ex);
+		   writeLock.unlock();
 		}
 	}
 	
@@ -312,6 +347,8 @@
 	// Native
 	// ------------------------------------------------------------------------------------------
 	
+	public static native void resetBuffer(ByteBuffer directByteBuffer, int size);
+	
 	private static native long init(String fileName, int maxIO, Logger logger);
 	
 	private native long size0(long handle);
@@ -343,7 +380,16 @@
       }
       public void run()
       {
-         pollEvents();
+         try
+         {
+            pollEvents();
+         }
+         finally
+         {
+            // This gives us extra protection in cases of interruption
+            // Case the poller thread is interrupted, this will allow us to restart the thread when required
+            AsynchronousFileImpl.this.poller = null;
+         }
       }
    }	
 }

Modified: trunk/src/main/org/jboss/messaging/core/config/Configuration.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/config/Configuration.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/config/Configuration.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -100,7 +100,11 @@
    String getJournalDirectory();
    
    void setJournalDirectory(String dir);
-
+   
+   String getPagingDirectory();
+   
+   void setPagingDirectory(String dir);
+   
    JournalType getJournalType();
    
    void setJournalType(JournalType type);
@@ -125,6 +129,10 @@
    
    void setJournalMaxAIO(int maxAIO);
    
+   void setJournalBufferReuseSize(int reuseSize);
+   
+   int getJournalBufferReuseSize();
+   
    boolean isCreateBindingsDir();
    
    void setCreateBindingsDir(boolean create);

Modified: trunk/src/main/org/jboss/messaging/core/config/impl/ConfigurationImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/config/impl/ConfigurationImpl.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/config/impl/ConfigurationImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -67,6 +67,8 @@
    
    public static final String DEFAULT_JOURNAL_DIR = "data/journal";
    
+   public static final String DEFAULT_PAGING_DIR = "data/paging";
+   
    public static final boolean DEFAULT_CREATE_JOURNAL_DIR = true;
    
    public static final JournalType DEFAULT_JOURNAL_TYPE = JournalType.ASYNCIO;
@@ -81,6 +83,7 @@
    
    public static final int DEFAULT_JOURNAL_MAX_AIO = 5000;
    
+   public static final int DEFAULT_JOURNAL_REUSE_BUFFER_SIZE = -1;   
    
    
    // Attributes -----------------------------------------------------------------------------
@@ -120,6 +123,8 @@
    
    protected String journalDirectory = DEFAULT_JOURNAL_DIR;
    
+   protected String pagingDirectory = DEFAULT_PAGING_DIR;
+   
    protected boolean createJournalDir = DEFAULT_CREATE_JOURNAL_DIR;
    
    public JournalType journalType = DEFAULT_JOURNAL_TYPE;
@@ -134,7 +139,9 @@
    
    protected int journalMaxAIO = DEFAULT_JOURNAL_MAX_AIO;
    
+   protected int journalBufferReuseSize = DEFAULT_JOURNAL_REUSE_BUFFER_SIZE;
    
+   
    public boolean isClustered()
    {
       return clustered;
@@ -270,6 +277,17 @@
 		return journalType;
 	}
 	
+	
+	public void setPagingDirectory(String dir)
+	{
+	   this.pagingDirectory = dir;
+	}
+	
+	public String getPagingDirectory()
+	{
+	   return this.pagingDirectory;
+	}
+	
 	public void setJournalType(JournalType type)
    {
       this.journalType = type;
@@ -365,6 +383,16 @@
 	   this.jmxManagementEnabled = enabled;
 	}
 	
+   public void setJournalBufferReuseSize(int reuseSize)
+   {
+      this.journalBufferReuseSize = reuseSize;
+   }
+   
+   public int getJournalBufferReuseSize()
+   {
+      return this.journalBufferReuseSize;
+   }	
+	
    public boolean equals(Object other)
    {
       if (this == other)

Modified: trunk/src/main/org/jboss/messaging/core/config/impl/FileConfiguration.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/config/impl/FileConfiguration.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/config/impl/FileConfiguration.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -311,6 +311,8 @@
       createBindingsDir = getBoolean(e, "create-bindings-dir", createBindingsDir);
 
       journalDirectory = getString(e, "journal-directory", journalDirectory);
+      
+      pagingDirectory = getString(e, "paging-directory", pagingDirectory);
 
       createJournalDir = getBoolean(e, "create-journal-dir", createJournalDir);
 
@@ -339,6 +341,8 @@
       journalSyncNonTransactional = getBoolean(e, "journal-sync-non-transactional", journalSyncNonTransactional);
 
       journalFileSize = getInteger(e, "journal-file-size", journalFileSize);
+      
+      journalBufferReuseSize = getInteger(e, "journal-buffer-reuse-size", journalBufferReuseSize);
 
       journalMinFiles = getInteger(e, "journal-min-files", journalMinFiles);
 

Modified: trunk/src/main/org/jboss/messaging/core/deployers/impl/QueueSettingsDeployer.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/deployers/impl/QueueSettingsDeployer.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/deployers/impl/QueueSettingsDeployer.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -45,6 +45,10 @@
    
    private static final String MAX_SIZE_BYTES_NODE_NAME = "max-size-bytes";
    
+   private static final String DROP_MESSAGES_WHEN_FULL_NODE_NAME = "drop-messages-when-full";
+   
+   private static final String PAGE_SIZE_BYTES_NODE_NAME = "page-size-bytes";
+   
    private static final String DISTRIBUTION_POLICY_CLASS_NODE_NAME = "distribution-policy-class";
    
    private static final String MESSAGE_COUNTER_HISTORY_DAY_LIMIT_NODE_NAME = "message-counter-history-day-limit";
@@ -105,6 +109,10 @@
          {
             queueSettings.setMaxSizeBytes(Integer.valueOf(child.getTextContent()));   
          }
+         else if (PAGE_SIZE_BYTES_NODE_NAME.equalsIgnoreCase(child.getNodeName()))
+         {
+            queueSettings.setPageSizeBytes(Integer.valueOf(child.getTextContent()));
+         }
          else if (DISTRIBUTION_POLICY_CLASS_NODE_NAME.equalsIgnoreCase(child.getNodeName()))
          {
             queueSettings.setDistributionPolicyClass(child.getTextContent());
@@ -113,6 +121,10 @@
          {
             queueSettings.setMessageCounterHistoryDayLimit(Integer.valueOf(child.getTextContent()));
          }
+         else if (DROP_MESSAGES_WHEN_FULL_NODE_NAME.equalsIgnoreCase(child.getNodeName()))
+         {
+            queueSettings.setDropMessagesWhenFull(Boolean.valueOf(child.getTextContent().trim()));
+         }
       }
       
       queueSettingsRepository.addMatch(match, queueSettings);

Added: trunk/src/main/org/jboss/messaging/core/journal/BufferCallback.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/journal/BufferCallback.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/journal/BufferCallback.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.journal;
+
+/**
+ * 
+ * This interface is defined here just to avoid a direct dependency to the asyncio package
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public interface BufferCallback extends org.jboss.messaging.core.asyncio.BufferCallback
+{
+   
+}

Modified: trunk/src/main/org/jboss/messaging/core/journal/SequentialFile.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/journal/SequentialFile.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/journal/SequentialFile.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -46,6 +46,8 @@
     */
    void open(int maxIO) throws Exception;
    
+   void setBufferCallback(BufferCallback callback);   
+   
    int getAlignment() throws Exception;
    
    int calculateBlockStart(int position) throws Exception;
@@ -70,4 +72,8 @@
    
    void close() throws Exception;
    
+   void sync() throws Exception;
+   
+   long size() throws Exception;
+   
 }

Modified: trunk/src/main/org/jboss/messaging/core/journal/SequentialFileFactory.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/journal/SequentialFileFactory.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/journal/SequentialFileFactory.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -48,4 +48,11 @@
    
    int getAlignment();
    
+   int calculateBlockSize(int bytes);
+   
+   /** This method is not being used currently. 
+    *  The journal will complete the buffer when reusing the buffer.
+    *  Look at JournalImpl#newBuffer for more information about this */
+   void clearBuffer(ByteBuffer buffer);
+   
 }

Modified: trunk/src/main/org/jboss/messaging/core/journal/impl/AIOSequentialFile.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/journal/impl/AIOSequentialFile.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/journal/impl/AIOSequentialFile.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -33,6 +33,7 @@
 import org.jboss.messaging.core.asyncio.AsynchronousFile;
 import org.jboss.messaging.core.asyncio.impl.AsynchronousFileImpl;
 import org.jboss.messaging.core.exception.MessagingException;
+import org.jboss.messaging.core.journal.BufferCallback;
 import org.jboss.messaging.core.journal.IOCallback;
 import org.jboss.messaging.core.journal.SequentialFile;
 import org.jboss.messaging.core.logging.Logger;
@@ -181,6 +182,11 @@
       
    }
    
+   public void setBufferCallback(BufferCallback callback)
+   {
+      aioFile.setBufferCallback(callback);
+   }
+   
    public void position(final int pos) throws Exception
    {
       position.set(pos);		
@@ -245,6 +251,16 @@
       }		
    }
    
+   public void sync() throws Exception
+   {
+      throw new IllegalArgumentException("This method is not supported on AIO");
+   }
+
+   public long size() throws Exception
+   {
+      return aioFile.size();
+   }
+
    public String toString()
    {
       return "AIOSequentialFile:" + this.journalDir + "/" + this.fileName;

Modified: trunk/src/main/org/jboss/messaging/core/journal/impl/AIOSequentialFileFactory.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/journal/impl/AIOSequentialFileFactory.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/journal/impl/AIOSequentialFileFactory.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -65,6 +65,11 @@
       return ByteBuffer.allocateDirect(size);
    }
    
+   public void clearBuffer(ByteBuffer directByteBuffer)
+   {
+      AsynchronousFileImpl.resetBuffer(directByteBuffer, directByteBuffer.limit());
+   }
+   
    public int getAlignment()
    {
       return 512;
@@ -77,4 +82,13 @@
       newbuffer.put(bytes);
       return newbuffer;
    }
+
+   public int calculateBlockSize(int position)
+   {
+      int alignment = getAlignment();
+      
+      int pos = ((position / alignment) + (position % alignment != 0 ? 1 : 0)) * alignment;
+      
+      return pos;
+   }
 }

Modified: trunk/src/main/org/jboss/messaging/core/journal/impl/JournalImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/journal/impl/JournalImpl.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/journal/impl/JournalImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -49,6 +49,7 @@
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.jboss.messaging.core.exception.MessagingException;
+import org.jboss.messaging.core.journal.BufferCallback;
 import org.jboss.messaging.core.journal.EncodingSupport;
 import org.jboss.messaging.core.journal.IOCallback;
 import org.jboss.messaging.core.journal.LoadManager;
@@ -143,7 +144,7 @@
    
    private boolean autoReclaim = true;
    
-   private AtomicInteger nextOrderingId = new AtomicInteger(0);
+   private final AtomicInteger nextOrderingId = new AtomicInteger(0);
    
    // used for Asynchronous IO only (ignored on NIO).
    private final int maxAIO;
@@ -176,6 +177,12 @@
    
    private ExecutorService filesExecutor = null;
    
+   private final int reuseBufferSize;
+   
+   private final ConcurrentLinkedQueue<ByteBuffer> reuseBuffers = new ConcurrentLinkedQueue<ByteBuffer>();
+   
+   private final BufferCallback bufferCallback = new LocalBufferCallback();
+   
    /*
     * We use a semaphore rather than synchronized since it performs better when
     * contended
@@ -210,7 +217,9 @@
    public JournalImpl(final int fileSize, final int minFiles,
                       final boolean syncTransactional, final boolean syncNonTransactional,
                       final SequentialFileFactory fileFactory, 
-                      final String filePrefix, final String fileExtension, final int maxAIO)
+                      final String filePrefix, final String fileExtension,
+                      final int maxAIO,
+                      final int reuseBufferSize)
    {
       if (fileSize < MIN_FILE_SIZE)
       {
@@ -241,6 +250,8 @@
          throw new IllegalStateException("maxAIO should aways be a positive number");
       }
       
+      this.reuseBufferSize = fileFactory.calculateBlockSize(reuseBufferSize); 
+      
       this.fileSize = fileSize;
       
       this.minFiles = minFiles;
@@ -271,7 +282,7 @@
       
       int size = SIZE_ADD_RECORD + recordLength;
       
-      ByteBufferWrapper bb = new ByteBufferWrapper(fileFactory.newBuffer(size));
+      ByteBufferWrapper bb = new ByteBufferWrapper(newBuffer(size));
       
       bb.putByte(ADD_RECORD);     
       bb.position(SIZE_BYTE + SIZE_INT); // skip ID part
@@ -305,7 +316,7 @@
             
       int size = SIZE_ADD_RECORD + record.length;
       
-      ByteBuffer bb = fileFactory.newBuffer(size);
+      ByteBuffer bb = newBuffer(size);
       
       bb.put(ADD_RECORD);
       bb.position(SIZE_BYTE + SIZE_INT); // skip ID part
@@ -347,7 +358,7 @@
       
       int size = SIZE_UPDATE_RECORD + record.length;
       
-      ByteBuffer bb = fileFactory.newBuffer(size); 
+      ByteBuffer bb = newBuffer(size); 
       
       bb.put(UPDATE_RECORD);     
       bb.position(SIZE_BYTE + SIZE_INT); // skip ID part
@@ -387,7 +398,7 @@
       
       int size = SIZE_UPDATE_RECORD + record.getEncodeSize();
       
-      ByteBufferWrapper bb = new ByteBufferWrapper(fileFactory.newBuffer(size));
+      ByteBufferWrapper bb = new ByteBufferWrapper(newBuffer(size));
       
       bb.putByte(UPDATE_RECORD);     
       bb.position(SIZE_BYTE + SIZE_INT); // skip ID part
@@ -428,7 +439,7 @@
       
       int size = SIZE_DELETE_RECORD;
       
-      ByteBuffer bb = fileFactory.newBuffer(size); 
+      ByteBuffer bb = newBuffer(size); 
       
       bb.put(DELETE_RECORD);     
       bb.position(SIZE_BYTE + SIZE_INT); // skip ID part
@@ -467,7 +478,7 @@
       
       int size = SIZE_ADD_RECORD_TX + recordLength;
       
-      ByteBufferWrapper bb = new ByteBufferWrapper(fileFactory.newBuffer(size)); 
+      ByteBufferWrapper bb = new ByteBufferWrapper(newBuffer(size)); 
       
       bb.putByte(ADD_RECORD_TX);
       bb.position(SIZE_BYTE + SIZE_INT); // skip ID part
@@ -504,7 +515,7 @@
       
       int size = SIZE_ADD_RECORD_TX + record.length;
       
-      ByteBuffer bb = fileFactory.newBuffer(size); 
+      ByteBuffer bb = newBuffer(size); 
       
       bb.put(ADD_RECORD_TX);
       bb.position(SIZE_BYTE + SIZE_INT); // skip ID part
@@ -541,7 +552,7 @@
       
       int size = SIZE_UPDATE_RECORD_TX + record.length; 
       
-      ByteBuffer bb = fileFactory.newBuffer(size); 
+      ByteBuffer bb = newBuffer(size); 
       
       bb.put(UPDATE_RECORD_TX);     
       bb.position(SIZE_BYTE + SIZE_INT); // skip ID part
@@ -569,6 +580,7 @@
       }
    }
    
+   
    public void appendUpdateRecordTransactional(final long txID, final long id, byte recordType, EncodingSupport record) throws Exception
    {
       if (state != STATE_LOADED)
@@ -578,7 +590,7 @@
       
       int size = SIZE_UPDATE_RECORD_TX + record.getEncodeSize(); 
       
-      ByteBufferWrapper bb = new ByteBufferWrapper(fileFactory.newBuffer(size)); 
+      ByteBufferWrapper bb = new ByteBufferWrapper(newBuffer(size)); 
             
       bb.putByte(UPDATE_RECORD_TX);     
       bb.position(SIZE_BYTE + SIZE_INT); // skip ID part
@@ -605,7 +617,7 @@
          lock.release();
       }
    }
-   
+
    public void appendDeleteRecordTransactional(final long txID, final long id) throws Exception
    {
       if (state != STATE_LOADED)
@@ -615,7 +627,7 @@
       
       int size = SIZE_DELETE_RECORD_TX;
       
-      ByteBuffer bb = fileFactory.newBuffer(size); 
+      ByteBuffer bb = newBuffer(size); 
       
       bb.put(DELETE_RECORD_TX);     
       bb.position(SIZE_BYTE + SIZE_INT); // skip ID part
@@ -718,7 +730,7 @@
       
       int size = SIZE_ROLLBACK_RECORD;
       
-      ByteBuffer bb = fileFactory.newBuffer(size); 
+      ByteBuffer bb = newBuffer(size); 
       
       bb.put(ROLLBACK_RECORD);      
       bb.position(SIZE_BYTE + SIZE_INT); // skip ID part
@@ -1191,6 +1203,11 @@
       {     
          currentFile.getFile().open();
          
+         if (this.reuseBufferSize > 0)
+         {
+            currentFile.getFile().setBufferCallback(bufferCallback);
+         }
+         
          currentFile.getFile().position(currentFile.getFile().calculateBlockStart(lastDataPos));
          
          currentFile.setOffset(currentFile.getFile().position());
@@ -1582,7 +1599,7 @@
    {
       int size = SIZE_COMPLETE_TRANSACTION_RECORD + tx.getElementsSummary().size() * SIZE_INT * 2;
       
-      ByteBuffer bb = fileFactory.newBuffer(size); 
+      ByteBuffer bb = newBuffer(size); 
       
       bb.put(recordType);    
       bb.position(SIZE_BYTE + SIZE_INT); // skip ID part
@@ -1709,7 +1726,7 @@
     * */
    private JournalFile appendRecord(final ByteBuffer bb, final boolean sync, final TransactionCallback callback) throws Exception
    {      
-      int size = bb.capacity();
+      int size = bb.limit();
       checkFile(size);
       bb.position(SIZE_BYTE);
       if (currentFile == null)
@@ -1734,6 +1751,7 @@
       return currentFile;
    }
    
+   
    private JournalFile createFile(final boolean keepOpened) throws Exception
    {
       int orderingID = generateOrderingID();
@@ -1773,6 +1791,10 @@
       file.getFile().open();
       file.getFile().position(file.getFile().calculateBlockStart(SIZE_HEADER));
       file.setOffset(file.getFile().calculateBlockStart(SIZE_HEADER));
+      if (this.reuseBufferSize > 0)
+      {
+         file.getFile().setBufferCallback(bufferCallback);
+      }
    }
    
    private int generateOrderingID()
@@ -1944,7 +1966,67 @@
          return null;
       }
    }
+   // -- Area reserved for the reuse buffer logic -----------------------------------------
    
+   private volatile long bufferReuseLastTime = System.currentTimeMillis();
+   private ByteBuffer newBuffer(int size)
+   {
+      // if a new buffer wasn't requested in 10 seconds, we clear the queue
+      // This is being done this way as we don't need another Timeout Thread just to cleanup this
+      if (reuseBufferSize > 0 && System.currentTimeMillis() - bufferReuseLastTime > 10000)
+      {
+         log.debug("Clearing reuse buffers queue with " + reuseBuffers.size() + " elements");
+         bufferReuseLastTime = System.currentTimeMillis();
+         reuseBuffers.clear();
+      }
+      
+      if (reuseBufferSize <= 0 || size > reuseBufferSize)
+      {
+         return fileFactory.newBuffer(size);
+      }
+      else
+      {
+
+         int alignedSize = fileFactory.calculateBlockSize(size);
+      
+         ByteBuffer buffer = this.reuseBuffers.poll();
+         if (buffer == null)
+         {
+            buffer = fileFactory.newBuffer(reuseBufferSize);
+            buffer.limit(alignedSize);
+         }
+         else
+         {
+            buffer.limit(alignedSize);
+
+            // we could gain some little performance if we could avoid clearing the buffer.
+            // On AIO this is being done with just a memset, what should be fairly quick
+            fileFactory.clearBuffer(buffer);
+         }
+         
+         buffer.rewind();
+
+         return buffer;         
+      }
+   }
+   
+   private class LocalBufferCallback implements BufferCallback
+   {
+
+      public void bufferDone(ByteBuffer buffer)
+      {
+         bufferReuseLastTime = System.currentTimeMillis();
+         if (buffer.capacity() == reuseBufferSize)
+         {
+            reuseBuffers.offer(buffer);
+         }
+      }
+      
+   }
+   
+   // ------------------------------------------------------------------------------------
+   
+   
    // Inner classes ---------------------------------------------------------------------------
    
    private static class TransactionCallback implements IOCallback

Modified: trunk/src/main/org/jboss/messaging/core/journal/impl/NIOSequentialFile.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/journal/impl/NIOSequentialFile.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/journal/impl/NIOSequentialFile.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -27,6 +27,7 @@
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 
+import org.jboss.messaging.core.journal.BufferCallback;
 import org.jboss.messaging.core.journal.IOCallback;
 import org.jboss.messaging.core.journal.SequentialFile;
 import org.jboss.messaging.core.logging.Logger;
@@ -53,6 +54,8 @@
    
    private RandomAccessFile rfile;
    
+   BufferCallback bufferCallback;
+   
    public NIOSequentialFile(final String journalDir, final String fileName)
    {
       this.journalDir = journalDir;
@@ -89,6 +92,13 @@
       open();
    }
    
+   
+   
+   public void setBufferCallback(BufferCallback callback)
+   {
+      this.bufferCallback = callback;
+   }
+
    public void fill(final int position, final int size, final byte fillCharacter) throws Exception
    {
       ByteBuffer bb = ByteBuffer.allocateDirect(size);
@@ -164,9 +174,14 @@
       
       if (sync)
       {
-         channel.force(false);
+         sync();
       }
       
+      if (bufferCallback != null)
+      {
+         bufferCallback.bufferDone(bytes);
+      }
+      
       return bytesRead;
    }
    
@@ -180,7 +195,13 @@
          {
             callback.done();
          }
+
+         if (bufferCallback != null)
+         {
+            bufferCallback.bufferDone(bytes);
+         }
          
+         
          return bytesRead;
       }
       catch (Exception e)
@@ -189,7 +210,18 @@
          throw e;
       }
    }
+      
+   public void sync() throws Exception
+   {
+      channel.force(false);
+   }
    
+   public long size() throws Exception
+   {
+      return channel.size();
+   }
+
+   
    public void position(final int pos) throws Exception
    {
       channel.position(pos);

Modified: trunk/src/main/org/jboss/messaging/core/journal/impl/NIOSequentialFileFactory.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/journal/impl/NIOSequentialFileFactory.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/journal/impl/NIOSequentialFileFactory.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -58,6 +58,19 @@
       return ByteBuffer.allocate(size);
    }
    
+   public void clearBuffer(final ByteBuffer buffer)
+   {
+      final int limit = buffer.limit();
+      buffer.rewind();
+      
+      for (int i = 0; i < limit; i++)
+      {
+         buffer.put((byte)0);
+      }
+
+      buffer.rewind();
+   }
+   
    public ByteBuffer wrapBuffer(final byte[] bytes)
    {
       return ByteBuffer.wrap(bytes);
@@ -67,6 +80,11 @@
    {
       return 1;
    }
+
+   public int calculateBlockSize(int bytes)
+   {
+      return bytes;
+   }
    
    
 }

Modified: trunk/src/main/org/jboss/messaging/core/management/QueueControlMBean.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/management/QueueControlMBean.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/management/QueueControlMBean.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -52,8 +52,6 @@
 
    long getSizeBytes();
 
-   int getMaxSizeBytes();
-
    int getMessageCount();
 
    long getScheduledCount();

Modified: trunk/src/main/org/jboss/messaging/core/management/impl/QueueControl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/management/impl/QueueControl.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/management/impl/QueueControl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -129,11 +129,6 @@
       return queue.getMessageCount();
    }
 
-   public int getMaxSizeBytes()
-   {
-      return queue.getMaxSizeBytes();
-   }
-
    public int getConsumerCount()
    {
       return queue.getConsumerCount();

Added: trunk/src/main/org/jboss/messaging/core/paging/LastPageRecord.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/paging/LastPageRecord.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/paging/LastPageRecord.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,73 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.paging;
+
+import org.jboss.messaging.core.journal.EncodingSupport;
+import org.jboss.messaging.util.SimpleString;
+
+/**
+ * 
+ * Stores the last pageID processed during depage, to detect duplications after the delete
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public interface LastPageRecord extends EncodingSupport
+{
+   
+   // Constants -----------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   // Public --------------------------------------------------------
+   
+   /** Internal field with the primary key, used on the journal/database */
+   long getRecordId();
+
+   /** Internal field with the primary key, used on the journal/database */
+   void setRecordId(long recordId);
+
+   SimpleString getDestination();
+
+   void setDestination(SimpleString destination);
+
+   /** Last Page ID*/
+   long getLastId();
+
+   /** Last Page ID*/
+   void setLastId(long lastId);
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------
+   
+}

Added: trunk/src/main/org/jboss/messaging/core/paging/Page.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/paging/Page.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/paging/Page.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.paging;
+
+
+/**
+ * 
+ * <p>Look at the <a href="http://wiki.jboss.org/auth/wiki/JBossMessaging2Paging">WIKI</a> for more information.</p>
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public interface Page
+{
+   
+   int getPageId();
+   
+   void write(PageMessage message) throws Exception;
+   
+   PageMessage[] read() throws Exception;
+   
+   int getSize();
+   
+   int getNumberOfMessages();
+   
+   void sync() throws Exception;
+   
+   void open() throws Exception;
+   
+   void close() throws Exception;
+   
+   void delete() throws Exception;
+   
+}

Added: trunk/src/main/org/jboss/messaging/core/paging/PageMessage.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/paging/PageMessage.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/paging/PageMessage.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.paging;
+
+import org.jboss.messaging.core.journal.EncodingSupport;
+import org.jboss.messaging.core.server.ServerMessage;
+
+
+/**
+ * 
+ * The record taken by Page.
+ * We can't just record the ServerMessage as we need other information (such as the TransactionID used during paging)
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public interface PageMessage extends EncodingSupport
+{
+   ServerMessage getMessage();
+
+   long getTransactionID();
+
+}

Added: trunk/src/main/org/jboss/messaging/core/paging/PageTransactionInfo.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/paging/PageTransactionInfo.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/paging/PageTransactionInfo.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,54 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.paging;
+
+import org.jboss.messaging.core.journal.EncodingSupport;
+
+/**
+ * 
+ * <p>Look at the <a href="http://wiki.jboss.org/auth/wiki/JBossMessaging2Paging">WIKI</a> for more information.</p>
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public interface PageTransactionInfo extends EncodingSupport
+{
+
+   void waitCompletion() throws InterruptedException;
+   
+   void complete();
+
+   long getRecordID();
+
+   void setRecordID(long id);
+
+   long getTransactionID();
+   
+   int increment();
+   
+   int decrement();
+   
+   int getNumberOfMessages();
+
+}

Modified: trunk/src/main/org/jboss/messaging/core/paging/PagingManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/paging/PagingManager.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/paging/PagingManager.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -22,20 +22,98 @@
 
 package org.jboss.messaging.core.paging;
 
-import org.jboss.messaging.core.server.MessageReference;
+import java.util.Collection;
+
+import org.jboss.messaging.core.postoffice.PostOffice;
 import org.jboss.messaging.core.server.MessagingComponent;
-import org.jboss.messaging.core.server.Queue;
+import org.jboss.messaging.core.server.ServerMessage;
+import org.jboss.messaging.util.SimpleString;
 
 /**
  * 
- * A PagingManager
+ * <p>Look at the <a href="http://wiki.jboss.org/auth/wiki/JBossMessaging2Paging">WIKI</a> for more information.</p>
  * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  *
  */
 public interface PagingManager extends MessagingComponent
 {
-   void pageReference(Queue queue, MessageReference ref);
+
+   /** To return the PageStore associated with the address */
+   public PagingStore getPageStore(SimpleString address) throws Exception;
    
-   MessageReference depageReference(Queue queue);
+   /** An injection point for the PostOffice to inject itself */
+   void setPostOffice(PostOffice postOffice);
+   
+   /**
+    * @param pagingStoreImpl 
+    * @return false if the listener can't handle more pages
+    */
+   boolean onDepage(int pageId, SimpleString destination, PagingStore pagingStoreImpl, PageMessage[] data) throws Exception;
+   
+   /**
+    * To be used by transactions only.
+    * If you're sure you will page if isPaging, just call the method page and look at its return. 
+    * @param destination
+    * @return
+    */
+   boolean isPaging(SimpleString destination) throws Exception;
+   
+   /**
+    * Page, only if destination is in page mode.
+    * @param message
+    * @return false if destination is not on page mode
+    */
+   boolean page(ServerMessage message) throws Exception;
+   
+   /**
+    * Page, only if destination is in page mode.
+    * @param message
+    * @return false if destination is not on page mode
+    */
+   boolean page(ServerMessage message, long transactionId) throws Exception;
+   
+   /**
+    * Point to inform/restoring Transactions used when the messages were added into paging
+    * */
+   void addTransaction(PageTransactionInfo pageTransaction);
+   
+   
+   /**
+    * Use this method to inform when a transaction was completed.
+    * @param transactionId
+    */
+   void completeTransaction(long transactionId);
+   
+   
+   /**
+    * 
+    * Duplication detection for paging processing
+    *  */
+   void loadLastPage(LastPageRecord lastPage) throws Exception;
+   
+   /** 
+    * 
+    * To be called when there are no more references to the message
+    * @param message
+    */
+   void messageDone(ServerMessage message) throws Exception;
+   
+   /** To be called when an message is being added to the address.
+    *  @return the current size of the queue, or -1 if the queue is full and it should drop the message */
+   long addSize(ServerMessage message) throws Exception;
+
+   /** Sync current-pages on disk for these destinations */
+   void sync(Collection<SimpleString> destinationsToSync) throws Exception;
+
+   /**
+    * When we stop depaging, The Last page record needs to removed.
+    * Or else the record could live forever on the journal. 
+    * @throws Exception 
+    * */
+   void clearLastPageRecord(LastPageRecord lastRecord) throws Exception;
+   
+   
+   
 }

Added: trunk/src/main/org/jboss/messaging/core/paging/PagingStore.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/paging/PagingStore.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/paging/PagingStore.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,92 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.paging;
+
+import org.jboss.messaging.core.server.MessagingComponent;
+import org.jboss.messaging.util.SimpleString;
+
+/**
+ * 
+ * <p>The implementation will take care of details such as PageSize.</p>
+ * <p>The producers will write directly to PagingStore and that will decide what
+ * Page file should be used based on configured size</p>
+ * 
+ * <p>Look at the <a href="http://wiki.jboss.org/auth/wiki/JBossMessaging2Paging">WIKI</a> for more information.</p>
+
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public interface PagingStore extends MessagingComponent
+{
+   
+   int getNumberOfPages();
+   
+   SimpleString getStoreName();
+   
+   /** Maximum number of bytes allowed in memory */ 
+   long getMaxSizeBytes();
+   
+   boolean isDroppedMessage();
+   
+   void setDroppedMessage(boolean droppedMessages);
+   
+   boolean isDropWhenMaxSize();
+   
+   long getPageSizeBytes();
+   
+   long getAddressSize();
+   
+   long addAddressSize(long add);
+   
+   /** @return true if paging was started, or false if paging was already started before this call */
+   boolean startPaging() throws Exception;
+   
+   boolean isPaging();
+   
+   void sync() throws Exception;
+   
+   boolean page(PageMessage message) throws Exception;
+   
+   /** 
+    * Remove the first page from the Writing Queue.
+    * The file will still exist until Page.delete is called, 
+    * So, case the system is reloaded the same Page will be loaded back if delete is not called.
+    * @return
+    * @throws Exception 
+    */
+   Page depage() throws Exception;
+   
+   /**
+    * 
+    * @param postOffice
+    * @return false if a thread was already started, or if not in page mode
+    * @throws Exception 
+    */
+   boolean startDepaging(PagingManager listener) throws Exception;
+
+   LastPageRecord getLastRecord();
+
+   void setLastRecord(LastPageRecord record);
+
+}

Added: trunk/src/main/org/jboss/messaging/core/paging/PagingStoreFactory.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/paging/PagingStoreFactory.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/paging/PagingStoreFactory.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,41 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.paging;
+
+import org.jboss.messaging.core.settings.impl.QueueSettings;
+
+
+
+/**
+ * The integration point between the PagingManger and the File System (aka SequentialFiles)
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public interface PagingStoreFactory
+{
+
+   PagingStore newStore(org.jboss.messaging.util.SimpleString destinationName, QueueSettings queueSettings);
+   
+}

Added: trunk/src/main/org/jboss/messaging/core/paging/impl/LastPageRecordImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/paging/impl/LastPageRecordImpl.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/paging/impl/LastPageRecordImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,124 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.paging.impl;
+
+import org.jboss.messaging.core.paging.LastPageRecord;
+import org.jboss.messaging.core.remoting.spi.MessagingBuffer;
+import org.jboss.messaging.util.SimpleString;
+
+/**
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public class LastPageRecordImpl implements LastPageRecord
+{
+   
+    // Constants -----------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   
+   private long recordId = 0;
+   private SimpleString destination;
+   private long lastId;
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   
+   
+   // Public --------------------------------------------------------
+
+   public LastPageRecordImpl(final long lastId, final SimpleString destination)
+   {
+      super();
+      this.lastId = lastId;
+      this.destination = destination;
+   }
+
+   public LastPageRecordImpl()
+   {
+      super();
+   }
+
+   public long getRecordId()
+   {
+      return recordId;
+   }
+
+   public void setRecordId(final long recordId)
+   {
+      this.recordId = recordId;
+   }
+
+   public SimpleString getDestination()
+   {
+      return destination;
+   }
+
+   public void setDestination(final SimpleString destination)
+   {
+      this.destination = destination;
+   }
+
+   public long getLastId()
+   {
+      return lastId;
+   }
+
+   public void setLastId(final long lastId)
+   {
+      this.lastId = lastId;
+   }
+   
+   
+   public void decode(final MessagingBuffer buffer)
+   {
+      lastId = buffer.getLong();
+      destination = buffer.getSimpleString();
+   }
+   
+   public void encode(final MessagingBuffer buffer)
+   {
+      buffer.putLong(lastId);
+      buffer.putSimpleString(destination);
+   }
+   
+   public int getEncodeSize()
+   {
+      return 8  + SimpleString.sizeofString(destination);
+   }
+
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------
+   
+}

Added: trunk/src/main/org/jboss/messaging/core/paging/impl/PageImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/paging/impl/PageImpl.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/paging/impl/PageImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,263 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.paging.impl;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.jboss.messaging.core.journal.IOCallback;
+import org.jboss.messaging.core.journal.SequentialFile;
+import org.jboss.messaging.core.journal.SequentialFileFactory;
+import org.jboss.messaging.core.paging.Page;
+import org.jboss.messaging.core.paging.PageMessage;
+import org.jboss.messaging.core.remoting.impl.ByteBufferWrapper;
+import org.jboss.messaging.util.VariableLatch;
+
+/**
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public class PageImpl implements Page
+{
+   
+   // Constants -----------------------------------------------------
+   
+   private static final int SIZE_INTEGER = 4;
+   
+   private static final int SIZE_BYTE = 1;
+   
+   public static final int SIZE_RECORD = SIZE_BYTE + SIZE_INTEGER + SIZE_BYTE; 
+   
+   public static final byte START_BYTE= (byte)'{';
+   public static final byte END_BYTE= (byte)'}';
+   
+   // Attributes ----------------------------------------------------
+   
+   private final int pageId;
+   private final AtomicInteger numberOfMessages = new AtomicInteger(0);
+   private final SequentialFile file;
+   private final SequentialFileFactory fileFactory;
+   private final PagingCallback callback;
+   private final AtomicInteger size = new AtomicInteger(0);
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   public PageImpl(final SequentialFileFactory factory, final SequentialFile file,final int pageId) throws Exception
+   {
+      this.pageId = pageId;
+      this.file = file;
+      this.fileFactory = factory;
+      if (factory.isSupportsCallbacks())
+      {
+         callback = new PagingCallback();
+      }
+      else
+      {
+         callback = null;
+      }
+   }
+   
+   
+   // Public --------------------------------------------------------
+
+   
+   // PagingFile implementation
+   
+   
+   public int getPageId()
+   {
+      return pageId;
+   }
+   
+   public PageMessage[] read() throws Exception
+   {
+      
+      ArrayList<PageMessage> messages = new ArrayList<PageMessage>();
+
+      ByteBuffer buffer = fileFactory.newBuffer((int)file.size());
+      file.position(0);
+      file.read(buffer);
+      
+      ByteBufferWrapper messageBuffer = new ByteBufferWrapper(buffer);
+      
+      while (buffer.hasRemaining())
+      {
+         final int position = buffer.position();
+         
+         byte byteRead = buffer.get();
+         
+         if (byteRead == START_BYTE)
+         {
+            if (buffer.position() + SIZE_INTEGER < buffer.limit())
+            {
+               int messageSize = buffer.getInt();
+               int oldPos = buffer.position();
+               if (buffer.position() + messageSize < buffer.limit() && buffer.get(oldPos + messageSize) == END_BYTE)
+               {
+                  PageMessage msg = instantiateObject();
+                  msg.decode(messageBuffer);
+                  messages.add(msg);
+               }
+               else
+               {
+                  buffer.position(position + 1); 
+               }
+            }
+         }
+         else
+         {
+            buffer.position(position + 1); 
+         }
+      }
+      
+      numberOfMessages.set(messages.size());
+      
+      return messages.toArray(instantiateArray(messages.size()));
+   }
+   
+   public void write(final PageMessage message) throws Exception
+   {
+      ByteBuffer buffer = fileFactory.newBuffer(message.getEncodeSize() + SIZE_RECORD);
+      buffer.put(START_BYTE);
+      buffer.putInt(message.getEncodeSize());
+      message.encode(new ByteBufferWrapper(buffer));
+      buffer.put(END_BYTE);
+      buffer.rewind();
+
+      if (callback != null)
+      {
+         callback.countUp();
+         file.write(buffer, callback);
+      }
+      else
+      {
+         file.write(buffer, false);
+      }
+      
+      numberOfMessages.incrementAndGet();
+      size.addAndGet(buffer.limit());
+      
+   }
+   
+   public void sync() throws Exception
+   {
+      if (callback != null)
+      {
+         callback.waitCompletion();
+      }
+      else
+      {
+         file.sync();
+      }
+   }
+   
+   public void open() throws Exception
+   {
+      file.open();
+      this.size.set((int)file.size());
+      file.position(0);
+   }
+   
+   public void close() throws Exception
+   {
+      file.close();
+   }
+   
+   public void delete() throws Exception
+   {
+      file.delete();
+   }
+   
+   public int getNumberOfMessages()
+   {
+      return numberOfMessages.intValue();
+   }
+   
+   public int getSize()
+   {
+      return this.size.intValue();
+   }
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   protected  PageMessage instantiateObject()
+   {
+      return new PageMessageImpl();
+   }
+
+   
+   protected PageMessage[] instantiateArray(final int size)
+   {
+      return new PageMessage[size];
+   }
+   
+   // Private -------------------------------------------------------
+   
+   
+   // Inner classes -------------------------------------------------
+
+   private static class PagingCallback implements IOCallback
+   {      
+      private final VariableLatch countLatch = new VariableLatch();
+      
+      private volatile String errorMessage = null;
+      
+      private volatile int errorCode = 0;
+      
+      public void countUp()
+      {
+         countLatch.up();
+      }
+      
+      public void done()
+      {
+         countLatch.down();
+      }
+      
+      public void waitCompletion() throws InterruptedException
+      {
+         countLatch.waitCompletion();
+         
+         if (errorMessage != null)
+         {
+            throw new IllegalStateException("Error on Callback: " + errorCode + " - " + errorMessage);
+         }
+      }
+      
+      public void onError(final int errorCode, final String errorMessage)
+      {
+         this.errorMessage = errorMessage;
+         this.errorCode = errorCode;
+         countLatch.down();
+      }
+      
+   }
+   
+}

Added: trunk/src/main/org/jboss/messaging/core/paging/impl/PageMessageImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/paging/impl/PageMessageImpl.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/paging/impl/PageMessageImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,109 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.paging.impl;
+
+import org.jboss.messaging.core.paging.PageMessage;
+import org.jboss.messaging.core.remoting.spi.MessagingBuffer;
+import org.jboss.messaging.core.server.ServerMessage;
+import org.jboss.messaging.core.server.impl.ServerMessageImpl;
+
+/**
+ * 
+ * This class is used to encapsulate ServerMessage and TransactionID on Paging
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public class PageMessageImpl implements PageMessage
+{
+   
+   // Constants -----------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   // Public --------------------------------------------------------
+
+   private final ServerMessage message;
+   private long transactionID;
+   
+   public PageMessageImpl(final ServerMessage message, final long transactionID)
+   {
+      this.message = message;
+      this.transactionID = transactionID;
+   }
+   
+   public PageMessageImpl(final ServerMessage message)
+   {
+      this.message = message;
+   }
+   
+   public PageMessageImpl()
+   {
+      this(new ServerMessageImpl());
+   }
+   
+   public ServerMessage getMessage()
+   {
+      return message;
+   }
+
+   public long getTransactionID()
+   {
+      return transactionID;
+   }
+   
+   
+   // EncodingSupport implementation --------------------------------
+
+   public void decode(final MessagingBuffer buffer)
+   {
+      transactionID = buffer.getLong();
+      message.decode(buffer);
+   }
+
+   public void encode(final MessagingBuffer buffer)
+   {
+      buffer.putLong(transactionID);
+      message.encode(buffer);
+   }
+
+   public int getEncodeSize()
+   {
+      
+      return 8 + message.getEncodeSize();
+   }
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------
+   
+}

Added: trunk/src/main/org/jboss/messaging/core/paging/impl/PageTransactionInfoImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/paging/impl/PageTransactionInfoImpl.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/paging/impl/PageTransactionInfoImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,152 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.paging.impl;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.jboss.messaging.core.paging.PageTransactionInfo;
+import org.jboss.messaging.core.remoting.spi.MessagingBuffer;
+
+/**
+ * 
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public class PageTransactionInfoImpl implements PageTransactionInfo
+{
+
+   // Constants -----------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   private long transactionID;
+   private long recordID;
+   private CountDownLatch countDownCompleted;
+   
+   final AtomicInteger numberOfMessages = new AtomicInteger(0);
+   
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   public PageTransactionInfoImpl(final long transactionID)
+   {
+      this.transactionID = transactionID;
+      this.countDownCompleted = new CountDownLatch(1);
+   }
+
+   public PageTransactionInfoImpl()
+   {
+   }
+
+   // Public --------------------------------------------------------
+
+   
+   public long getRecordID()
+   {
+      return recordID;
+   }
+   
+   public void setRecordID(long recordID)
+   {
+      this.recordID = recordID;
+   }
+   
+   public long getTransactionID()
+   {
+      return transactionID;
+   }
+   
+   public int increment()
+   {
+      return numberOfMessages.incrementAndGet();
+   }
+   
+   public int decrement()
+   {
+      final int value = numberOfMessages.decrementAndGet();
+      if (value < 0)
+      {
+         throw new IllegalStateException("Internal error Negative value on Paging transactions!");
+      }
+      
+      return value;
+   }
+   
+   public int getNumberOfMessages()
+   {
+      return numberOfMessages.get();
+   }
+   
+   // EncodingSupport implementation 
+   
+   public synchronized void decode(final MessagingBuffer buffer)
+   {
+      this.transactionID = buffer.getLong();
+      this.numberOfMessages.set(buffer.getInt());
+      this.countDownCompleted = null; // if it is being readed, certainly it was committed
+   }
+   
+   public synchronized void encode(final MessagingBuffer buffer)
+   {
+      buffer.putLong(this.transactionID);
+      buffer.putInt(this.numberOfMessages.get());
+   }
+
+   public synchronized int getEncodeSize()
+   {
+      return 8 /* long */ + 4 /* int */;
+   }
+
+   public void complete()
+   {
+      /** 
+       * this is to avoid a race condition where the transaction still being committed another thread is depaging messages
+       */
+      countDownCompleted.countDown();
+   }
+   
+   /** 
+    * this is to avoid a race condition where the transaction still being committed another thread is depaging messages
+    */
+   public void waitCompletion() throws InterruptedException
+   {
+      if (countDownCompleted != null)
+      {
+         countDownCompleted.await();
+      }
+   }
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------
+   
+}

Added: trunk/src/main/org/jboss/messaging/core/paging/impl/PagingManagerFactoryNIO.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/paging/impl/PagingManagerFactoryNIO.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/paging/impl/PagingManagerFactoryNIO.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,94 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.paging.impl;
+
+import java.io.File;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+import org.jboss.messaging.core.journal.SequentialFileFactory;
+import org.jboss.messaging.core.journal.impl.NIOSequentialFileFactory;
+import org.jboss.messaging.core.paging.PagingStore;
+import org.jboss.messaging.core.paging.PagingStoreFactory;
+import org.jboss.messaging.core.settings.impl.QueueSettings;
+import org.jboss.messaging.util.SimpleString;
+
+/**
+ * 
+ * Integration point between Paging and NIO
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public class PagingManagerFactoryNIO implements PagingStoreFactory
+{
+   
+   // Constants -----------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   private final String directory;
+   
+   private final Executor executor;
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   public PagingManagerFactoryNIO(final String directory)
+   {
+      this.directory = directory;
+      this.executor = Executors.newSingleThreadExecutor();
+   }
+   
+   public PagingManagerFactoryNIO(final String directory, final Executor executor)
+   {
+      this.directory = directory;
+      this.executor = executor;
+   }
+   
+   // Public --------------------------------------------------------
+
+   public PagingStore newStore(final SimpleString destinationName, QueueSettings settings)
+   {
+      final String destinationDirectory = directory + "/" + destinationName.toString();
+      File destinationFile = new File(destinationDirectory);
+      destinationFile.mkdirs();
+      
+      return new PagingStoreImpl(newFileFactory(destinationDirectory), destinationName, settings, executor);
+   }
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   protected SequentialFileFactory newFileFactory(final String destinationDirectory)
+   {
+      return new NIOSequentialFileFactory(destinationDirectory);
+   }
+
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------
+   
+}

Added: trunk/src/main/org/jboss/messaging/core/paging/impl/PagingManagerImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/paging/impl/PagingManagerImpl.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/paging/impl/PagingManagerImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,411 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.paging.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.jboss.messaging.core.logging.Logger;
+import org.jboss.messaging.core.paging.LastPageRecord;
+import org.jboss.messaging.core.paging.PageMessage;
+import org.jboss.messaging.core.paging.PageTransactionInfo;
+import org.jboss.messaging.core.paging.PagingManager;
+import org.jboss.messaging.core.paging.PagingStore;
+import org.jboss.messaging.core.paging.PagingStoreFactory;
+import org.jboss.messaging.core.persistence.StorageManager;
+import org.jboss.messaging.core.postoffice.PostOffice;
+import org.jboss.messaging.core.postoffice.impl.PostOfficeImpl;
+import org.jboss.messaging.core.server.MessageReference;
+import org.jboss.messaging.core.server.ServerMessage;
+import org.jboss.messaging.core.settings.HierarchicalRepository;
+import org.jboss.messaging.core.settings.impl.QueueSettings;
+import org.jboss.messaging.util.SimpleString;
+
+/**
+ *  <p>Look at the <a href="http://wiki.jboss.org/auth/wiki/JBossMessaging2Paging">WIKI</a> for more information.</p>
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ *
+ */
+public class PagingManagerImpl implements PagingManager
+{
+
+   
+   // Constants -----------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   private volatile boolean started = false;
+   
+   private final ConcurrentMap<SimpleString, PagingStore> stores = new ConcurrentHashMap<SimpleString, PagingStore>();
+   
+   private final HierarchicalRepository<QueueSettings> queueSettingsRepository;
+   
+   private final PagingStoreFactory pagingSPI;
+   
+   private final StorageManager storageManager;
+
+   private PostOffice postOffice;
+   
+   private final ConcurrentMap</*TransactionID*/ Long , PageTransactionInfo> transactions = new ConcurrentHashMap<Long, PageTransactionInfo>();
+   
+
+   
+   // Static --------------------------------------------------------------------------------------------------------------------------
+
+   private static final Logger log = Logger.getLogger(PostOfficeImpl.class);
+   
+   //private static final boolean isTrace = log.isTraceEnabled();
+   private static final boolean isTrace = true;
+   
+   // This is just a debug tool method.
+   // During debugs you could make log.trace as log.info, and change the variable isTrace above
+   private static void trace(String message)
+   {
+      //log.trace(message);
+      log.info(message);
+   }
+   
+   
+   // Constructors --------------------------------------------------------------------------------------------------------------------
+   
+   public PagingManagerImpl(final PagingStoreFactory pagingSPI, StorageManager storageManager, 
+                            final HierarchicalRepository<QueueSettings> queueSettingsRepository)
+   {
+      this.pagingSPI = pagingSPI;
+      this.queueSettingsRepository = queueSettingsRepository;
+      this.storageManager = storageManager;
+   }
+   
+   // Public ---------------------------------------------------------------------------------------------------------------------------
+   
+   // PagingManager implementation -----------------------------------------------------------------------------------------------------
+   
+   public PagingStore getPageStore(final SimpleString storeName) throws Exception
+   {
+      validateStarted();
+      
+      PagingStore store = stores.get(storeName);
+      if (store == null)
+      {
+         
+         store = newStore(storeName);
+         
+         PagingStore oldStore = stores.putIfAbsent(storeName, store);
+         
+         if (oldStore != null)
+         {
+            store = oldStore;
+         }
+         
+         store.start();
+      }
+
+      return store;
+      
+   }
+   
+   /** this will be set by the postOffice itself.
+    *  There is no way to set this on the constructor as the PagingManager is constructed before the postOffice.
+    *  (There is a one-to-one relationship here) */
+   public void setPostOffice(PostOffice postOffice)
+   {
+      this.postOffice = postOffice;
+   }
+
+   public void clearLastPageRecord(LastPageRecord lastRecord) throws Exception
+   {
+      trace("Clearing lastRecord information " + lastRecord.getLastId());
+      storageManager.storeDelete(lastRecord.getRecordId());
+   }
+   
+   /**
+    * This method will remove files from the page system and add them into the journal, doing it transactionally
+    * 
+    * A Transaction will be opened only if persistent messages are used.
+    * If persistent messages are also used, it will update eventual PageTransactions
+    */
+   public boolean onDepage(int pageId, final SimpleString destination, PagingStore pagingStore, final PageMessage[] data) throws Exception
+   {
+      log.info("Depaging....");
+      
+      /// Depage has to be done atomically, in case of failure it should be back to where it was
+      final long depageTransactionID = storageManager.generateTransactionID();
+      
+      LastPageRecord lastPage = pagingStore.getLastRecord(); 
+      
+      if (lastPage == null)
+      {
+         lastPage = new LastPageRecordImpl(pageId, destination);
+         pagingStore.setLastRecord(lastPage);
+      }
+      else
+      {
+         if (pageId <= lastPage.getLastId())
+         {
+            log.warn("Page " + pageId + " was already processed, ignoring the page");
+            return true;
+         }
+      }
+
+      lastPage.setLastId(pageId);
+      storageManager.storeLastPage(depageTransactionID, lastPage);
+      
+      HashSet<PageTransactionInfo> pageTransactionsToUpdate = new HashSet<PageTransactionInfo>();
+
+      final List<MessageReference> refsToAdd = new ArrayList<MessageReference>();
+      
+      for (PageMessage msg: data)
+      {
+         final long transactionIdDuringPaging = msg.getTransactionID();
+         if (transactionIdDuringPaging > 0)
+         {
+            final PageTransactionInfo pageTransactionInfo = transactions.get(transactionIdDuringPaging);
+            
+            // http://wiki.jboss.org/auth/wiki/JBossMessaging2Paging
+            // This is the Step D described on the "Transactions on Paging" section
+            if (pageTransactionInfo == null)
+            {
+               if (isTrace)
+               {
+                  trace("Transaction " + msg.getTransactionID() + " not found, ignoring message " + msg.getMessage().getMessageID());
+               }
+               continue;
+            }
+            
+            // This is to avoid a race condition where messages are depaged before the commit arrived
+            pageTransactionInfo.waitCompletion();
+
+            /// Update information about transactions
+            if (msg.getMessage().isDurable())
+            {
+               pageTransactionInfo.decrement();
+               pageTransactionsToUpdate.add(pageTransactionInfo);
+            }
+         }
+         
+         msg.getMessage().setMessageID(storageManager.generateMessageID());
+
+         refsToAdd.addAll(postOffice.route(msg.getMessage()));
+         
+         if (msg.getMessage().getDurableRefCount() != 0)
+         {
+            storageManager.storeMessageTransactional(depageTransactionID, msg.getMessage());
+         }
+      }
+      
+      
+      for (PageTransactionInfo pageWithTransaction: pageTransactionsToUpdate)
+      {
+         if (pageWithTransaction.getNumberOfMessages() == 0)
+         { 
+            // http://wiki.jboss.org/auth/wiki/JBossMessaging2Paging
+            // numberOfReads==numberOfWrites -> We delete the record
+            storageManager.storeDeleteTransactional(depageTransactionID, pageWithTransaction.getRecordID());
+            this.transactions.remove(pageWithTransaction.getTransactionID());
+         }
+         else
+         {
+            storageManager.storePageTransaction(depageTransactionID, pageWithTransaction);
+         }
+      }
+      
+      storageManager.commit(depageTransactionID);
+
+      for (MessageReference ref : refsToAdd)
+      {
+         ref.getQueue().addLast(ref);
+      }
+      
+      return pagingStore.getAddressSize() < pagingStore.getMaxSizeBytes(); 
+   }
+   
+   public void loadLastPage(LastPageRecord lastPage) throws Exception
+   {
+      System.out.println("LastPage loaded was " + lastPage.getLastId() + " recordID = " + lastPage.getRecordId());
+      this.getPageStore(lastPage.getDestination()).setLastRecord(lastPage);
+   }
+
+   public boolean isPaging(SimpleString destination) throws Exception
+   {
+      return this.getPageStore(destination).isPaging();
+   }
+   
+   public void messageDone(ServerMessage message) throws Exception
+   {
+      addSize(message.getDestination(), message.getEncodeSize() * -1);
+   }
+   
+   public long addSize(final ServerMessage message) throws Exception
+   {
+      return addSize(message.getDestination(), message.getEncodeSize());      
+   }
+   
+   public boolean page(ServerMessage message, long transactionId)
+         throws Exception
+   {
+      return this.getPageStore(message.getDestination()).page(new PageMessageImpl(message, transactionId));
+   }
+
+
+   public boolean page(ServerMessage message) throws Exception
+   {
+      return this.getPageStore(message.getDestination()).page(new PageMessageImpl(message));
+   }
+
+   
+   public void addTransaction(PageTransactionInfo pageTransaction)
+   {
+      this.transactions.put(pageTransaction.getTransactionID(), pageTransaction);
+   }
+
+   public void completeTransaction(long transactionId)
+   {
+      PageTransactionInfo pageTrans = this.transactions.get(transactionId);
+      
+      // If nothing was paged.. we just remove the information to avoid memory leaks
+      if (pageTrans.getNumberOfMessages() == 0)
+      {
+         this.transactions.remove(pageTrans);
+      }
+   }
+   
+   public void sync(Collection<SimpleString> destinationsToSync) throws Exception
+   {
+      for (SimpleString destination: destinationsToSync)
+      {
+         this.getPageStore(destination).sync();
+      }
+   }
+   
+   // MessagingComponent implementation ------------------------------------------------------------------------------------------------
+   
+   public boolean isStarted()
+   {
+      return started;
+   }
+   
+   public void start() throws Exception
+   {
+      this.started = true;
+      
+   }
+   
+   public void stop() throws Exception
+   {
+      this.started = false;
+      
+      for (PagingStore store: stores.values())
+      {
+         store.stop();
+      }
+   }
+   
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   private PagingStore newStore(final SimpleString destinationName)
+   {
+      return pagingSPI.newStore(destinationName, this.queueSettingsRepository.getMatch(destinationName.toString()));
+   }
+   
+   private void validateStarted()
+   {
+      if (!started)
+      {
+         throw new IllegalStateException("PagingManager is not started");
+      }
+   }
+
+   
+   private long addSize(final SimpleString destination, final long size) throws Exception
+   {
+      final PagingStore store = this.getPageStore(destination);
+      
+      final long maxSize = store.getMaxSizeBytes();
+      
+      final long pageSize = store.getPageSizeBytes();
+
+      if (store.isDropWhenMaxSize() && size > 0)
+      {
+         if (store.getAddressSize() + size > maxSize)
+         {
+            if (!store.isDroppedMessage())
+            {
+               store.setDroppedMessage(true);
+               log.warn("Messages are being dropped on adress " + store.getStoreName());
+            }
+            
+            return -1l;
+         }
+         else
+         {
+            return store.addAddressSize(size);
+         }
+      }
+      else
+      {
+         final long addressSize = store.addAddressSize(size);
+
+         if (size > 0)
+         {
+            if (maxSize > 0 && addressSize > maxSize)
+            {
+               if (store.startPaging())
+               {
+                  if (isTrace)
+                  {
+                     trace("Starting paging on " + destination + ", size = " + addressSize + ", maxSize=" + maxSize);
+                  }
+               }
+            }
+         }
+         else
+         {
+            if ( maxSize > 0 && addressSize < (maxSize - pageSize))
+            {
+               if (store.startDepaging(this))
+               {
+                  log.info("Starting depaging Thread, size = " + addressSize);
+               }
+            }
+         }
+         
+         return addressSize;
+      }
+   }
+
+   
+   // Inner classes -------------------------------------------------
+   
+}

Added: trunk/src/main/org/jboss/messaging/core/paging/impl/PagingStoreImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/paging/impl/PagingStoreImpl.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/paging/impl/PagingStoreImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,653 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.paging.impl;
+
+import java.text.DecimalFormat;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.jboss.messaging.core.journal.SequentialFile;
+import org.jboss.messaging.core.journal.SequentialFileFactory;
+import org.jboss.messaging.core.logging.Logger;
+import org.jboss.messaging.core.paging.LastPageRecord;
+import org.jboss.messaging.core.paging.Page;
+import org.jboss.messaging.core.paging.PageMessage;
+import org.jboss.messaging.core.paging.PagingManager;
+import org.jboss.messaging.core.settings.impl.QueueSettings;
+import org.jboss.messaging.util.SimpleString;
+
+/**
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public class PagingStoreImpl implements TestSupportPageStore
+{
+
+   // Constants -----------------------------------------------------
+   private static final Logger log = Logger.getLogger(PagingStoreImpl.class);
+   
+   // Attributes ----------------------------------------------------
+   
+   private final DecimalFormat format = new DecimalFormat("000000000");
+   
+   private final AtomicInteger pageUsedSize = new AtomicInteger(0);
+   
+   private final SimpleString storeName;
+   
+   private final SequentialFileFactory fileFactory;
+   
+   private final long maxSize;
+   
+   private final long pageSize;
+   
+   private final boolean dropMessagesOnSize;
+   
+   private boolean droppedMessages;
+   
+   private final Executor executor;
+   
+   // Bytes consumed by the queue on the memory
+   private final AtomicLong sizeInBytes = new AtomicLong();
+   
+   private volatile Runnable dequeueThread;
+   private volatile int numberOfPages;
+   private volatile int firstPageId = Integer.MAX_VALUE;
+   private volatile int currentPageId;
+   private volatile Page currentPage;
+
+   // positioningGlobalLock protects opening/closing and messing up with positions (currentPage and IDs)
+   private final Semaphore positioningGlobalLock = new Semaphore(1); 
+
+   private final ReadWriteLock lock = new ReentrantReadWriteLock();
+   private volatile boolean initialized = false;
+
+   private volatile LastPageRecord lastPageRecord;
+   
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   
+   public PagingStoreImpl(final SequentialFileFactory fileFactory, final SimpleString storeName, QueueSettings queueSettings, Executor executor) 
+   {
+      this.fileFactory = fileFactory;
+      this.storeName = storeName;
+      this.maxSize = queueSettings.getMaxSizeBytes();
+      this.pageSize = queueSettings.getPageSizeBytes();
+      this.dropMessagesOnSize = queueSettings.isDropMessagesWhenFull();
+      this.executor = executor;
+   }
+   
+   
+   // Public --------------------------------------------------------
+
+   // PagingStore implementation ------------------------------------
+   
+   
+   public boolean isDroppedMessage()
+   {
+      return droppedMessages;
+   }
+   
+   public void setDroppedMessage(boolean droppedMessages)
+   {
+      this.droppedMessages = droppedMessages;
+   }
+
+   
+   public long getAddressSize()
+   {
+      return sizeInBytes.get();
+   }
+   
+   public long addAddressSize(long delta)
+   {
+      return sizeInBytes.addAndGet(delta);
+   }
+
+   /** Maximum number of bytes allowed in memory */ 
+   public long getMaxSizeBytes()
+   {
+      return maxSize;
+   }
+   
+   public boolean isDropWhenMaxSize()
+   {
+      return dropMessagesOnSize;
+   }
+
+   public long getPageSizeBytes()
+   {
+      return pageSize;
+   }
+
+   
+   public boolean isPaging()
+   {
+      lock.readLock().lock();
+      try
+      {
+         return currentPage != null;
+      }
+      finally
+      {
+         lock.readLock().unlock();
+      }
+   }
+   
+   public int getNumberOfPages()
+   {
+      return numberOfPages;
+   }
+   
+   public SimpleString getStoreName()
+   {
+      return storeName;
+   }
+   
+   /** 
+    *  It returns a Page out of the Page System without reading it. 
+    *  The method calling this method will remove the page and will start reading it outside of any locks. 
+    *  
+    * */
+   public Page depage() throws Exception
+   {
+      validateInit();
+      
+      positioningGlobalLock.acquire(); // Can't change currentPage or any of ids without a global lock
+      lock.writeLock().lock();  // Wait pending writes to finish before entering the block
+      
+      try
+      {
+         
+         if (numberOfPages == 0)
+         {
+            return null;
+         }
+         else
+         {
+
+            numberOfPages--;
+            
+            final Page returnPage;
+            if (currentPageId == firstPageId)
+            {
+               firstPageId = Integer.MAX_VALUE;
+
+               if (currentPage != null)
+               {
+                  returnPage = currentPage;
+                  returnPage.close();
+                  currentPage = null;
+               }
+               else
+               {
+                  // sanity check... it shouldn't happen!
+                  throw new IllegalStateException("CurrentPage is null");
+               }
+               
+               if (returnPage.getNumberOfMessages() == 0)
+               {
+                  returnPage.open();
+                  returnPage.delete();
+                  return null;
+               }
+               else
+               {
+                  openNewPage();
+               }
+
+               
+               
+               return returnPage;
+            }
+            else
+            {
+               returnPage =  createPage(firstPageId++);
+            }
+            
+            return returnPage;
+         }
+      }
+      finally
+      {
+         lock.writeLock().unlock();
+         positioningGlobalLock.release();
+      }
+      
+   }
+
+   public boolean page(final PageMessage message) throws Exception
+   {
+      validateInit();
+      
+      // Max-size is set, but reject is activated, what means.. never page on this address
+      if (dropMessagesOnSize)
+      {
+         return false;
+      }
+      
+      int bytesToWrite = fileFactory.calculateBlockSize(message.getEncodeSize() + PageImpl.SIZE_RECORD);
+      
+      
+      // The only thing single-threaded done on paging is positioning and check-files (verifying if we need to open a new page file)
+      positioningGlobalLock.acquire();
+
+      // After we have it locked we keep all the threads working until we need to move to a new file (in which case we demand a writeLock, to wait for the writes to finish)
+      try
+      {
+         if (currentPage == null)
+         {
+            return false;
+         }
+         
+         if ((pageUsedSize.addAndGet(bytesToWrite) > this.pageSize && currentPage.getNumberOfMessages() > 0))
+         {
+            // Wait any pending write on the current page to finish before we can open another page.
+            lock.writeLock().lock();
+            try
+            {
+               openNewPage();
+               pageUsedSize.addAndGet(bytesToWrite);
+            }
+            finally
+            {
+               lock.writeLock().unlock();
+            }
+         }
+         // we must get the readLock before we release the synchronizedBlockLock
+         // or else we could end up with files records being added to the currentPage even if the max size was already achieved.
+         // (Condition tested by PagingStoreTestPage::testConcurrentPaging, The test would eventually fail, 1 in 100)
+         // This is because the checkSize and positioning has to be done protected. We only allow writing the file in multi-thread.
+         lock.readLock().lock();
+
+      }
+      finally
+      {
+         positioningGlobalLock.release();
+      }
+      
+      // End of a synchronized block..
+      
+      try
+      {
+         if (currentPage != null)
+         {
+            currentPage.write(message);
+            return true;
+         }
+         else
+         {
+            return false;
+         }
+      }
+      finally
+      {
+         lock.readLock().unlock();
+      }
+   }
+   
+   public void sync() throws Exception
+   {
+      validateInit();
+      
+      lock.readLock().lock();
+      
+      try
+      {
+         currentPage.sync();
+      }
+      finally
+      {
+         lock.readLock().unlock();
+      }
+   }
+   
+   public boolean startDepaging(final PagingManager manager) throws Exception
+   {
+      lock.readLock().lock();
+      try
+      {
+         if (currentPage == null)
+         {
+            return false;
+         }
+         else
+         {
+            synchronized (this)
+            {
+               if (this.dequeueThread == null)
+               {
+                  this.dequeueThread = new DepageRunnable(manager);
+                  executor.execute(this.dequeueThread);
+                  return true;
+               }
+               else
+               {
+                  return false;
+               }
+            }
+         }
+      }
+      finally
+      {
+         lock.readLock().unlock();
+      }
+   }
+   
+   
+   public LastPageRecord getLastRecord()
+   {
+      return lastPageRecord;
+   }
+
+   public void setLastRecord(LastPageRecord record)
+   {
+      this.lastPageRecord = record;
+   }
+
+   
+   
+   // MessagingComponent implementation
+   
+   public synchronized boolean isStarted()
+   {
+      return initialized;
+   }
+   
+   public synchronized void stop() throws Exception
+   {
+      if (initialized)
+      {
+         lock.writeLock().lock();
+         
+         try
+         {
+            initialized = false;
+            if (currentPage != null)
+            {
+               currentPage.close();            
+            }
+         }
+         finally
+         {
+            lock.writeLock().unlock();
+         }
+      }
+   }
+
+   
+   public synchronized void start() throws Exception
+   {
+
+      if (initialized)
+      {
+         // don't throw an exception.
+         // You could have two threads adding PagingStore to a ConcurrentHashMap,
+         // and having both threads calling init. One of the calls should just need to be ignored
+         return;
+       }
+      
+      lock.writeLock().lock();
+      
+      firstPageId = Integer.MAX_VALUE;
+      currentPageId = 0;
+      currentPage = null;
+      
+      try
+      {
+         
+         List<String> files = fileFactory.listFiles("page");
+         
+         numberOfPages = files.size();
+         
+         for (String fileName: files)
+         {
+            final int fileId = getPageIdFromFileName(fileName);
+            
+            if (fileId > currentPageId)
+            {
+               currentPageId = fileId;
+            }
+            
+            if (fileId < firstPageId)
+            {
+               firstPageId = fileId;
+            }
+         }
+         
+         initialized = true;
+
+         if (numberOfPages != 0)
+         {
+            startPaging();
+         }
+      }
+      finally
+      {
+         lock.writeLock().unlock();
+      }
+   }
+   
+   public boolean startPaging() throws Exception
+   {
+      validateInit();
+
+      
+      // First check without any global locks.
+      // (Faster)
+      lock.readLock().lock();
+      try
+      {
+         if (currentPage != null)
+         {
+            return false;
+         }
+      }
+      finally
+      {
+         lock.readLock().unlock();
+      }
+      
+      
+      // if the first check failed, we do it again under a global lock (positioningGlobalLock) this time
+      positioningGlobalLock.acquire();
+      
+      try
+      {
+         if (currentPage == null)
+         {
+            openNewPage();
+            return true;
+         }
+         else
+         {
+            return false;
+         }
+      }
+      finally
+      {
+         positioningGlobalLock.release();
+      }
+   }
+   
+   
+   
+   // TestSupportPageStore ------------------------------------------
+   
+   public void forceAnotherPage() throws Exception
+   {
+      validateInit();
+      openNewPage();
+   }
+   
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   
+   // Private -------------------------------------------------------
+
+   
+   private synchronized void clearDequeueThread()
+   {
+      this.dequeueThread = null;
+   }
+   
+
+   private void openNewPage() throws Exception
+   {
+      lock.writeLock().lock();
+      
+      try
+      {
+         numberOfPages++;
+         currentPageId++;
+         
+         if (currentPageId < firstPageId)
+         {
+            firstPageId = currentPageId;
+         }
+         
+         if (currentPage != null)
+         {
+            currentPage.close();
+         }
+         
+         currentPage = createPage(currentPageId);
+         
+         pageUsedSize.set(0);
+         
+         currentPage.open();
+         
+      }
+      finally
+      {
+         lock.writeLock().unlock();
+      }
+   }
+
+
+   private Page createPage(final int page) throws Exception
+   {
+      String fileName = createFileName(page);
+      SequentialFile file = fileFactory.createSequentialFile(fileName, 1000);
+      
+      file.open();
+      
+      long size = file.size();
+      
+      if (fileFactory.isSupportsCallbacks() && size < this.pageSize)
+      {
+         file.fill((int)size, (int)(pageSize - size), (byte)0);
+      }
+      
+      file.position(0);
+      
+      file.close();
+      
+      return new PageImpl(fileFactory, file, page);
+   }
+   
+   /**
+    * 
+    * Note: Decimalformat is not thread safe, Use synchronization before calling this method
+    * 
+    * @param pageID
+    * @return
+    */
+   private String createFileName(int pageID)
+   {
+      return format.format(pageID) + ".page";
+   }
+   
+   private static int getPageIdFromFileName(String fileName)
+   {
+      return Integer.parseInt(fileName.substring(0, fileName.indexOf('.')));
+   }
+   
+   private void validateInit()
+   {
+      if (!initialized)
+      {
+         throw new IllegalStateException("PagingStore " + this.storeName + " not initialized!");
+      }
+   }
+   
+   // Inner classes -------------------------------------------------
+   
+   class DepageRunnable implements Runnable
+   {
+      final PagingManager manager;
+      
+      public DepageRunnable(final PagingManager manager)
+      {
+         this.manager = manager;
+      }
+      
+      
+      public void run()
+      {
+         try
+         {
+            boolean needMorePages = false;
+            do
+            {
+               Page page = depage();
+               if (page == null)
+               {
+                  if (lastPageRecord != null)
+                  {
+                     manager.clearLastPageRecord(lastPageRecord);
+                  }
+                  lastPageRecord = null;
+                  break;
+               }
+               page.open();
+               PageMessage messages[] = page.read();
+               needMorePages = manager.onDepage(page.getPageId(), PagingStoreImpl.this.storeName, PagingStoreImpl.this, messages);
+               page.delete();
+            }
+            while (needMorePages);
+         }
+         catch (Exception e)
+         {
+            log.error(e, e);
+         }
+         finally
+         {
+            PagingStoreImpl.this.clearDequeueThread();
+         }
+      }
+   }
+   
+}

Added: trunk/src/main/org/jboss/messaging/core/paging/impl/TestSupportPageStore.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/paging/impl/TestSupportPageStore.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/paging/impl/TestSupportPageStore.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.paging.impl;
+
+import org.jboss.messaging.core.paging.PagingStore;
+
+/**
+ * All the methods required to TestCases on  PageStoreImpl
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public interface TestSupportPageStore extends PagingStore
+{
+   void forceAnotherPage() throws Exception;
+}

Modified: trunk/src/main/org/jboss/messaging/core/persistence/StorageManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/persistence/StorageManager.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/persistence/StorageManager.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -25,6 +25,8 @@
 import java.util.List;
 import java.util.Map;
 
+import org.jboss.messaging.core.paging.LastPageRecord;
+import org.jboss.messaging.core.paging.PageTransactionInfo;
 import org.jboss.messaging.core.postoffice.Binding;
 import org.jboss.messaging.core.postoffice.PostOffice;
 import org.jboss.messaging.core.server.MessageReference;
@@ -72,6 +74,12 @@
    void rollback(long txID) throws Exception;
       
    
+   void storePageTransaction(long txID, PageTransactionInfo pageTransaction) throws Exception;
+
+   
+   void storeLastPage(long txID, LastPageRecord pageTransaction) throws Exception;
+   
+   
    void updateDeliveryCount(MessageReference ref) throws Exception;     
    
    void loadMessages(PostOffice postOffice, Map<Long, Queue> queues) throws Exception;

Modified: trunk/src/main/org/jboss/messaging/core/persistence/impl/journal/JournalStorageManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/persistence/impl/journal/JournalStorageManager.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/persistence/impl/journal/JournalStorageManager.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -47,6 +47,11 @@
 import org.jboss.messaging.core.journal.impl.JournalImpl;
 import org.jboss.messaging.core.journal.impl.NIOSequentialFileFactory;
 import org.jboss.messaging.core.logging.Logger;
+import org.jboss.messaging.core.paging.LastPageRecord;
+import org.jboss.messaging.core.paging.PageTransactionInfo;
+import org.jboss.messaging.core.paging.PagingManager;
+import org.jboss.messaging.core.paging.impl.LastPageRecordImpl;
+import org.jboss.messaging.core.paging.impl.PageTransactionInfoImpl;
 import org.jboss.messaging.core.persistence.StorageManager;
 import org.jboss.messaging.core.postoffice.Binding;
 import org.jboss.messaging.core.postoffice.PostOffice;
@@ -97,6 +102,10 @@
    
    public static final byte UPDATE_DELIVERY_COUNT = 33;
    
+   public static final byte PAGE_TRANSACTION = 34;
+   
+   public static final byte LAST_PAGE = 35;
+   
    public static final byte SET_SCHEDULED_DELIVERY_TIME = 44;
   	
 	private final AtomicLong messageIDSequence = new AtomicLong(0);
@@ -129,7 +138,7 @@
 			
 	   SequentialFileFactory bindingsFF = new NIOSequentialFileFactory(bindingsDir);
       
-	   bindingsJournal = new JournalImpl(1024 * 1024, 2, true, true, bindingsFF, "jbm-bindings", "bindings", 1);
+	   bindingsJournal = new JournalImpl(1024 * 1024, 2, true, true, bindingsFF, "jbm-bindings", "bindings", 1, -1);
 	      
 	   String journalDir = config.getJournalDirectory();
 	   
@@ -172,7 +181,7 @@
 	   messageJournal = new JournalImpl(config.getJournalFileSize(), 
 	   		config.getJournalMinFiles(), config.isJournalSyncTransactional(),
 	   		config.isJournalSyncNonTransactional(), journalFF,
-	   		"jbm-data", "jbm", config.getJournalMaxAIO());
+	   		"jbm-data", "jbm", config.getJournalMaxAIO(), config.getJournalBufferReuseSize());
 	}
 	
 	/* This constructor is only used for testing */
@@ -217,7 +226,29 @@
    {
       messageJournal.appendAddRecordTransactional(txID, message.getMessageID(), ADD_MESSAGE, message);
    }
+
+   public void storePageTransaction(long txID, PageTransactionInfo pageTransaction) throws Exception
+   {
+      if (pageTransaction.getRecordID() != 0)
+      {
+         // Instead of updating the record, we delete the old one as that is better for reclaiming
+         messageJournal.appendDeleteRecordTransactional(txID, pageTransaction.getRecordID());
+      }
+      pageTransaction.setRecordID(generateMessageID());
+      messageJournal.appendAddRecordTransactional(txID, pageTransaction.getRecordID(), PAGE_TRANSACTION, pageTransaction);
+   }
    
+   public void storeLastPage(long txID, LastPageRecord lastPage) throws Exception
+   {
+      if (lastPage.getRecordId() != 0)
+      {
+         // To avoid linked list effect on reclaiming, we delete and add a new record, instead of simply updating it
+         messageJournal.appendDeleteRecordTransactional(txID, lastPage.getRecordId());
+      }
+      lastPage.setRecordId(generateMessageID());
+      messageJournal.appendAddRecordTransactional(txID, lastPage.getRecordId(), LAST_PAGE, lastPage);
+   }
+
    public void storeAcknowledgeTransactional(long txID, long queueID, long messageID) throws Exception
    {
    	EncodingSupport record = ackBytes(queueID, messageID);
@@ -285,6 +316,38 @@
 			
 			switch (recordType)
 			{
+			   case PAGE_TRANSACTION:
+			   {
+               MessagingBuffer buff = new ByteBufferWrapper(bb);
+               
+               PageTransactionInfoImpl pageTransactionInfo = new PageTransactionInfoImpl();
+               
+               pageTransactionInfo.decode(buff);
+               
+               pageTransactionInfo.setRecordID(record.id);
+               
+               PagingManager pagingManager = postOffice.getPagingManager();
+               
+               pagingManager.addTransaction(pageTransactionInfo);
+
+               break;
+			   }
+			   case LAST_PAGE:
+			   {
+               MessagingBuffer buff = new ByteBufferWrapper(bb);
+               
+			      LastPageRecordImpl recordImpl = new LastPageRecordImpl();
+			      
+			      recordImpl.setRecordId(record.id);
+			      
+			      recordImpl.decode(buff);
+               
+               PagingManager pagingManager = postOffice.getPagingManager();
+               
+               pagingManager.loadLastPage(recordImpl);
+			      
+			      break;
+			   }
 				case ADD_MESSAGE:
 				{
 					MessagingBuffer buff = new ByteBufferWrapper(bb);

Modified: trunk/src/main/org/jboss/messaging/core/persistence/impl/nullpm/NullStorageManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/persistence/impl/nullpm/NullStorageManager.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/persistence/impl/nullpm/NullStorageManager.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -26,6 +26,8 @@
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicLong;
 
+import org.jboss.messaging.core.paging.LastPageRecord;
+import org.jboss.messaging.core.paging.PageTransactionInfo;
 import org.jboss.messaging.core.persistence.StorageManager;
 import org.jboss.messaging.core.postoffice.Binding;
 import org.jboss.messaging.core.postoffice.PostOffice;
@@ -117,7 +119,15 @@
 	{
 	}
 
-	public void updateDeliveryCount(MessageReference ref) throws Exception
+	public void storePageTransaction(long txID, PageTransactionInfo pageTransaction) throws Exception
+   {
+   }
+
+   public void updatePageTransaction(long txID, PageTransactionInfo pageTransaction) throws Exception
+   {
+   }
+
+   public void updateDeliveryCount(MessageReference ref) throws Exception
 	{
 	}
 
@@ -155,5 +165,10 @@
 	{
 	   return started;
 	}
-  
+
+   public void storeLastPage(long txID, LastPageRecord pageTransaction) throws Exception
+   {
+   }
+
+
 }

Modified: trunk/src/main/org/jboss/messaging/core/postoffice/PostOffice.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/postoffice/PostOffice.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/postoffice/PostOffice.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -27,6 +27,8 @@
 import java.util.Set;
 
 import org.jboss.messaging.core.filter.Filter;
+import org.jboss.messaging.core.paging.PagingManager;
+import org.jboss.messaging.core.paging.impl.PageMessageImpl;
 import org.jboss.messaging.core.server.MessageReference;
 import org.jboss.messaging.core.server.MessagingComponent;
 import org.jboss.messaging.core.server.ServerMessage;
@@ -82,4 +84,6 @@
    Set<SimpleString> listAllDestinations();
    
    void setBackup(boolean backup);
+   
+   PagingManager getPagingManager();
 }

Modified: trunk/src/main/org/jboss/messaging/core/postoffice/impl/PostOfficeImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/postoffice/impl/PostOfficeImpl.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/postoffice/impl/PostOfficeImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -37,6 +37,8 @@
 import org.jboss.messaging.core.filter.Filter;
 import org.jboss.messaging.core.logging.Logger;
 import org.jboss.messaging.core.management.ManagementService;
+import org.jboss.messaging.core.paging.PagingManager;
+import org.jboss.messaging.core.paging.PagingStore;
 import org.jboss.messaging.core.persistence.StorageManager;
 import org.jboss.messaging.core.postoffice.Binding;
 import org.jboss.messaging.core.postoffice.FlowController;
@@ -75,13 +77,15 @@
    
    private final StorageManager storageManager;
    
+   private final PagingManager pagingManager;
+   
    private volatile boolean started;
 
    private volatile boolean backup;
 
    private final ManagementService managementService;
-  
-   public PostOfficeImpl(final StorageManager storageManager,
+   
+   public PostOfficeImpl(final StorageManager storageManager, final PagingManager pagingManager,
    		                final QueueFactory queueFactory, final ManagementService managementService, final boolean checkAllowable)
    {
       this.storageManager = storageManager;
@@ -91,12 +95,21 @@
       this.managementService = managementService;
       
       this.checkAllowable = checkAllowable;
+      
+      this.pagingManager = pagingManager;
    }
       
    // MessagingComponent implementation ---------------------------------------
    
    public void start() throws Exception
    {
+      if (pagingManager != null)
+      {
+         this.pagingManager.setPostOffice(this);
+   
+         pagingManager.start();
+      }
+      
       loadBindings();
       
       started = true;
@@ -104,6 +117,8 @@
 
    public void stop() throws Exception
    {
+      pagingManager.stop();
+      
       mappings.clear();
       
       destinations.clear();
@@ -130,7 +145,7 @@
       	{
       		storageManager.addDestination(address);     
       	}
-      	 
+      	
          flowControllers.put(address, new FlowControllerImpl(address, this));
          managementService.registerAddress(address);
    	}
@@ -213,42 +228,53 @@
    {
       return nameMap.get(queueName);
    }
-         
+   
    public List<MessageReference> route(final ServerMessage message) throws Exception
    {
-      SimpleString address = message.getDestination();
-          
-      if (checkAllowable)
-      {
-         if (!destinations.contains(address))
-         {
-            throw new MessagingException(MessagingException.ADDRESS_DOES_NOT_EXIST,
-                                         "Cannot route to address " + address);
-         }
-      }
-           
-      List<Binding> bindings = mappings.get(address);
       
-      List<MessageReference> refs = new ArrayList<MessageReference>();
+      long size = pagingManager.addSize(message);
       
-      if (bindings != null)
+      if (size < 0)
       {
-         for (Binding binding: bindings)
+         return new ArrayList<MessageReference>();
+      }
+      else
+      {
+         SimpleString address = message.getDestination();
+             
+         if (checkAllowable)
          {
-            Queue queue = binding.getQueue();
-            
-            Filter filter = queue.getFilter();
-            
-            if (filter == null || filter.match(message))
-            {                      
-               MessageReference reference = message.createReference(queue);              
+            if (!destinations.contains(address))
+            {
+               throw new MessagingException(MessagingException.ADDRESS_DOES_NOT_EXIST,
+                                            "Cannot route to address " + address);
+            }
+         }
+              
+         List<Binding> bindings = mappings.get(address);
+         
+         List<MessageReference> refs = new ArrayList<MessageReference>();
+         
+         if (bindings != null)
+         {
+            for (Binding binding: bindings)
+            {
+               Queue queue = binding.getQueue();
                
-               refs.add(reference);
+               Filter filter = queue.getFilter();
+               
+               if (filter == null || filter.match(message))
+               {                      
+                  MessageReference reference = message.createReference(queue);              
+                  
+                  refs.add(reference);
+               }
             }
          }
+
+         return refs;
       }
          
-      return refs;
    }
    
 //   public void routeFromCluster(final String address, final Message message) throws Exception
@@ -272,7 +298,13 @@
 //         }
 //      }
 //   }
+   
+   public PagingManager getPagingManager()
+   {
+      return this.pagingManager;
+   }
 
+
    public Map<SimpleString, List<Binding>> getMappings()
    {
       return mappings;
@@ -292,7 +324,7 @@
          binding.getQueue().setBackup(backup);
       }
    }
-
+   
    // Private -----------------------------------------------------------------
    
    private Binding createBinding(final SimpleString address, final SimpleString name, final Filter filter,
@@ -401,6 +433,12 @@
       }
                  
       storageManager.loadMessages(this, queues);
+      
+      for (SimpleString destination: dests)
+      {
+         PagingStore store = pagingManager.getPageStore(destination);
+         store.startDepaging(pagingManager);
+      }
    }
 
 }

Modified: trunk/src/main/org/jboss/messaging/core/server/Queue.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/server/Queue.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/server/Queue.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -42,6 +42,7 @@
  * 
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @author <a href="ataylor at redhat.com">Andy Taylor</a>
+ * @author <a href="clebert.suconic at jboss.com">Clebert Suconic</a>
  *
  */
 public interface Queue
@@ -50,6 +51,8 @@
    
    HandleStatus addFirst(MessageReference ref);
    
+   QueueSettings getSettings();
+   
    /**
     * This method is used to add a List of MessageReferences atomically at the head of the list.
     * Useful when cancelling messages and guaranteeing ordering
@@ -84,8 +87,6 @@
    void referenceCancelled();
    
    int getScheduledCount();
-          
-   int getMaxSizeBytes();
    
    int getSizeBytes();
    

Modified: trunk/src/main/org/jboss/messaging/core/server/ServerMessage.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/server/ServerMessage.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/server/ServerMessage.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -29,6 +29,7 @@
  * A ServerMessage
  * 
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
  *
  */
 public interface ServerMessage extends Message
@@ -41,10 +42,14 @@
 
    int decrementDurableRefCount();
    
-   int incrementDurableRefCount();
+   int incrementReference(boolean durable);
    
    int getDurableRefCount();
    
+   int decrementRefCount();
+   
+   int getRefCount();
+   
    ServerMessage copy();
 }
 

Modified: trunk/src/main/org/jboss/messaging/core/server/impl/MessageReferenceImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/server/impl/MessageReferenceImpl.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/server/impl/MessageReferenceImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -137,8 +137,7 @@
 
       if (maxDeliveries > 0 && deliveryCount >= maxDeliveries)
       {
-         log
-         .warn("Message has reached maximum delivery attempts, sending it to DLQ");
+         log.warn("Message has reached maximum delivery attempts, sending it to DLQ");
          sendToDLQ(persistenceManager, postOffice, queueSettingsRepository);
          
          return false;

Modified: trunk/src/main/org/jboss/messaging/core/server/impl/MessagingServerImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/server/impl/MessagingServerImpl.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/server/impl/MessagingServerImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -37,6 +37,10 @@
 import org.jboss.messaging.core.logging.Logger;
 import org.jboss.messaging.core.management.ManagementService;
 import org.jboss.messaging.core.management.MessagingServerControlMBean;
+import org.jboss.messaging.core.paging.PagingManager;
+import org.jboss.messaging.core.paging.PagingStoreFactory;
+import org.jboss.messaging.core.paging.impl.PagingManagerFactoryNIO;
+import org.jboss.messaging.core.paging.impl.PagingManagerImpl;
 import org.jboss.messaging.core.persistence.StorageManager;
 import org.jboss.messaging.core.postoffice.PostOffice;
 import org.jboss.messaging.core.postoffice.impl.PostOfficeImpl;
@@ -94,11 +98,13 @@
    // wired components
 
    private SecurityStore securityStore;
-   private HierarchicalRepository<QueueSettings> queueSettingsRepository = new HierarchicalObjectRepository<QueueSettings>();
+   private final HierarchicalRepository<QueueSettings> queueSettingsRepository = new HierarchicalObjectRepository<QueueSettings>();
    private ScheduledExecutorService scheduledExecutor;   
    private QueueFactory queueFactory;
+   private PagingStoreFactory storeFactory;
+   private PagingManager pagingManager;
    private PostOffice postOffice;
-   private ExecutorFactory executorFactory = new OrderedExecutorFactory(Executors.newCachedThreadPool(new JBMThreadFactory("JBM-async-session-delivery-threads")));
+   private final ExecutorFactory executorFactory = new OrderedExecutorFactory(Executors.newCachedThreadPool(new JBMThreadFactory("JBM-async-session-delivery-threads")));
    private HierarchicalRepository<Set<Role>> securityRepository;
    private ResourceManager resourceManager;   
    private MessagingServerPacketHandler serverPacketHandler;
@@ -183,9 +189,14 @@
       securityStore = new SecurityStoreImpl(configuration.getSecurityInvalidationInterval(), configuration.isSecurityEnabled());  
       queueSettingsRepository.setDefault(new QueueSettings());
       scheduledExecutor = new ScheduledThreadPoolExecutor(configuration.getScheduledThreadPoolMaxSize(), new JBMThreadFactory("JBM-scheduled-threads"));                  
-      queueFactory = new QueueFactoryImpl(scheduledExecutor, queueSettingsRepository);     
+      queueFactory = new QueueFactoryImpl(scheduledExecutor, queueSettingsRepository);
+      
+      
+      PagingStoreFactory storeFactory = new PagingManagerFactoryNIO(configuration.getPagingDirectory());
+      
+      pagingManager = new PagingManagerImpl(storeFactory, storageManager, queueSettingsRepository);
          
-      postOffice = new PostOfficeImpl(storageManager, queueFactory, managementService, configuration.isRequireDestinations());
+      postOffice = new PostOfficeImpl(storageManager, pagingManager, queueFactory, managementService, configuration.isRequireDestinations());
                        
       securityRepository = new HierarchicalObjectRepository<Set<Role>>();
       securityRepository.setDefault(new HashSet<Role>());

Modified: trunk/src/main/org/jboss/messaging/core/server/impl/QueueFactoryImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/server/impl/QueueFactoryImpl.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/server/impl/QueueFactoryImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -58,8 +58,7 @@
    {
       QueueSettings queueSettings = queueSettingsRepository.getMatch(name.toString());
             
-      Queue queue = new QueueImpl(persistenceID, name, filter, queueSettings.isClustered(), durable,
-      		queueSettings.getMaxSizeBytes(), scheduledExecutor);
+      Queue queue = new QueueImpl(persistenceID, name, filter, queueSettings.isClustered(), durable, queueSettings, scheduledExecutor);
 
       queue.setDistributionPolicy(queueSettings.getDistributionPolicy());
 

Modified: trunk/src/main/org/jboss/messaging/core/server/impl/QueueImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/server/impl/QueueImpl.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/server/impl/QueueImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -66,6 +66,7 @@
  * 
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @author <a href="ataylor at redhat.com">Andy Taylor</a>
+ * @author <a href="clebert.suconic at jboss.com">Clebert Suconic</a>
  * 
  */
 public class QueueImpl implements Queue
@@ -86,8 +87,6 @@
 
    private final boolean durable;
 
-   private final int maxSizeBytes;
-     
    private final ScheduledExecutorService scheduledExecutor;
 
    private final PriorityLinkedList<MessageReference> messageReferences =
@@ -119,11 +118,13 @@
    
    private final Lock lock = new ReentrantLock(false);
    
+   private final QueueSettings settings;
+   
    private volatile boolean backup;
          
    public QueueImpl(final long persistenceID, final SimpleString name,
          final Filter filter, final boolean clustered, final boolean durable,
-         final int maxSizeBytes,
+         final QueueSettings settings,
          final ScheduledExecutorService scheduledExecutor)
    {
       this.persistenceID = persistenceID;
@@ -136,9 +137,9 @@
 
       this.durable = durable;
 
-      this.maxSizeBytes = maxSizeBytes;
-
       this.scheduledExecutor = scheduledExecutor;
+      
+      this.settings = settings;
 
       direct = true;
    }
@@ -146,6 +147,12 @@
    // Queue implementation
    // -------------------------------------------------------------------
 
+
+   public QueueSettings getSettings()
+   {
+      return this.settings;
+   }
+
    public boolean isClustered()
    {
       return clustered;
@@ -430,11 +437,6 @@
       deliveringCount.decrementAndGet();
    }
 
-   public int getMaxSizeBytes()
-   {
-      return maxSizeBytes;
-   }
-   
    public int getSizeBytes()
    {
       return sizeBytes.get();
@@ -669,11 +671,6 @@
 
    private synchronized HandleStatus add(final MessageReference ref, final boolean first)
    {
-      if (maxSizeBytes != -1 && sizeBytes.get() + ref.getMessage().getEncodeSize() >= maxSizeBytes)
-      {
-         return HandleStatus.BUSY;              
-      }
-      
       if (!first)
       {
          messagesAdded.incrementAndGet();

Modified: trunk/src/main/org/jboss/messaging/core/server/impl/ServerMessageImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/server/impl/ServerMessageImpl.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/server/impl/ServerMessageImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -36,6 +36,7 @@
  * 
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @author <a href="mailto:ataylor at redhat.com">Andy Taylor</a>
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
  *
  */
 public class ServerMessageImpl extends MessageImpl implements ServerMessage
@@ -43,6 +44,9 @@
    private long messageID;
     
    private final AtomicInteger durableRefCount = new AtomicInteger(0);
+   
+   /** Global reference counts for paging control */
+   private final AtomicInteger refCount = new AtomicInteger(0);
               
    /*
     * Constructor for when reading from network
@@ -99,6 +103,8 @@
          durableRefCount.incrementAndGet();
       }
       
+      refCount.incrementAndGet();
+      
       return ref;
    }
    
@@ -112,11 +118,26 @@
       return durableRefCount.decrementAndGet();
    }
    
-   public int incrementDurableRefCount()
+   public int incrementReference(boolean durable)
    {
-      return durableRefCount.incrementAndGet();
+      if (durable)
+      {
+         durableRefCount.incrementAndGet();
+      }
+      
+      return refCount.incrementAndGet();
    }
      
+   public int decrementRefCount()
+   {
+      return refCount.decrementAndGet();
+   }
+
+   public int getRefCount()
+   {
+      return refCount.get();
+   }
+
    public ServerMessage copy()
    {
       return new ServerMessageImpl(this);

Modified: trunk/src/main/org/jboss/messaging/core/server/impl/ServerSessionImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/server/impl/ServerSessionImpl.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/server/impl/ServerSessionImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -39,6 +39,7 @@
 import org.jboss.messaging.core.filter.Filter;
 import org.jboss.messaging.core.filter.impl.FilterImpl;
 import org.jboss.messaging.core.logging.Logger;
+import org.jboss.messaging.core.paging.PagingManager;
 import org.jboss.messaging.core.persistence.StorageManager;
 import org.jboss.messaging.core.postoffice.Binding;
 import org.jboss.messaging.core.postoffice.FlowController;
@@ -131,6 +132,8 @@
    private final ResourceManager resourceManager;
    
    private final PostOffice postOffice;
+   
+   private final PagingManager pager;
 
    private final SecurityStore securityStore;
    
@@ -181,6 +184,8 @@
       
       this.postOffice = postOffice;
       
+      this.pager = postOffice.getPagingManager();
+      
       this.queueSettingsRepository = queueSettingsRepository;
       
       this.resourceManager = resourceManager;
@@ -350,22 +355,27 @@
          }
          throw e;         
       }
-
-      msg.setMessageID(storageManager.generateMessageID());
       
       if (autoCommitSends)
       {
-         List<MessageReference> refs = postOffice.route(msg);
+         if (!pager.page(msg))
+         {
+            // We only set the messageID after we are sure the message is not being paged
+            // Paged messages won't have an ID until they are depaged 
+            msg.setMessageID(storageManager.generateMessageID());
 
-         if (msg.getDurableRefCount() != 0)
-         {
-            storageManager.storeMessage(msg);
+            List<MessageReference> refs = postOffice.route(msg);
+   
+            if (msg.getDurableRefCount() != 0)
+            {
+               storageManager.storeMessage(msg);
+            }
+            
+            for (MessageReference ref : refs)
+            {
+               ref.getQueue().addLast(ref);
+            }
          }
-         
-         for (MessageReference ref : refs)
-         {
-            ref.getQueue().addLast(ref);
-         }
       }
       else
       {
@@ -544,6 +554,10 @@
          }
          finally
          {
+            
+         }
+         //finally (TODO: enable this back)
+         {
             //Now unlock
             
             for (Queue queue: locked)
@@ -1079,7 +1093,10 @@
 
          SimpleString filterString = filter == null ? null : filter.getFilterString();
 
-         response = new SessionQueueQueryResponseMessage(queue.isDurable(), queue.getMaxSizeBytes(),
+         QueueSettings settings = queue.getSettings();
+         
+         // TODO: Remove MAX-SIZE-BYTES from SessionQueueQueryResponse.
+         response = new SessionQueueQueryResponseMessage(queue.isDurable(), settings.getMaxSizeBytes(),
                  queue.getConsumerCount(), queue.getMessageCount(),
                  filterString, binding.getAddress());
       }
@@ -1215,6 +1232,11 @@
 
       Queue queue = ref.getQueue();
       
+      if (message.decrementRefCount() == 0)
+      {
+         pager.messageDone(message);
+      }
+      
       if (message.isDurable() && queue.isDurable())
       {
          int count = message.decrementDurableRefCount();

Modified: trunk/src/main/org/jboss/messaging/core/settings/impl/QueueSettings.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/settings/impl/QueueSettings.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/settings/impl/QueueSettings.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -43,6 +43,8 @@
    public static final DistributionPolicy DEFAULT_DISTRIBUTION_POLICY = new RoundRobinDistributionPolicy();
    public static final Boolean DEFAULT_CLUSTERED = false;
    public static final Integer DEFAULT_MAX_SIZE_BYTES = -1;
+   public static final Boolean DEFAULT_DROP_MESSAGES_WHEN_FULL = Boolean.FALSE;
+   public static final Integer DEFAULT_PAGE_SIZE_BYTES = 10 * 1024 * 1024; // 10M Bytes
    public static final Integer DEFAULT_MAX_DELIVERY_ATTEMPTS = 10;
    public static final Integer DEFAULT_MESSAGE_COUNTER_HISTORY_DAY_LIMIT = 0;
    public static final Long DEFAULT_REDELIVER_DELAY = (long) 500;
@@ -50,6 +52,8 @@
 
    private Boolean clustered = null;
    private Integer maxSizeBytes = null;
+   private Integer pageSizeBytes = null;
+   private Boolean dropMessagesWhenFull = null;
    private String distributionPolicyClass = null;
    private Integer maxDeliveryAttempts = null;
    private Integer messageCounterHistoryDayLimit = null;
@@ -72,6 +76,27 @@
       this.clustered = clustered;
    }
 
+   public Integer getPageSizeBytes()
+   {
+      return pageSizeBytes != null ? pageSizeBytes : DEFAULT_PAGE_SIZE_BYTES;
+   }
+   
+   
+   public Boolean isDropMessagesWhenFull()
+   {
+      return dropMessagesWhenFull != null ? this.dropMessagesWhenFull : DEFAULT_DROP_MESSAGES_WHEN_FULL;
+   }
+   
+   public void setDropMessagesWhenFull(Boolean value)
+   {
+      this.dropMessagesWhenFull = value;
+   }
+   
+   public void setPageSizeBytes(Integer pageSize)
+   {
+      this.pageSizeBytes = pageSize;
+   }
+   
    public Integer getMaxSizeBytes()
    {
       return maxSizeBytes != null ? maxSizeBytes:DEFAULT_MAX_SIZE_BYTES;
@@ -213,10 +238,18 @@
       {
          maxDeliveryAttempts = merged.maxDeliveryAttempts;
       }
+      if (dropMessagesWhenFull == null)
+      {
+         dropMessagesWhenFull = merged.dropMessagesWhenFull;
+      }
       if(maxSizeBytes == null)
       {
          maxSizeBytes = merged.maxSizeBytes;
       }
+      if (pageSizeBytes == null)
+      {
+         pageSizeBytes = merged.getPageSizeBytes();
+      }
       if(messageCounterHistoryDayLimit == null)
       {
          messageCounterHistoryDayLimit = merged.messageCounterHistoryDayLimit;

Modified: trunk/src/main/org/jboss/messaging/core/transaction/impl/TransactionImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/transaction/impl/TransactionImpl.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/core/transaction/impl/TransactionImpl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -24,6 +24,7 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -32,6 +33,8 @@
 
 import org.jboss.messaging.core.exception.MessagingException;
 import org.jboss.messaging.core.logging.Logger;
+import org.jboss.messaging.core.paging.PagingManager;
+import org.jboss.messaging.core.paging.impl.PageTransactionInfoImpl;
 import org.jboss.messaging.core.persistence.StorageManager;
 import org.jboss.messaging.core.postoffice.PostOffice;
 import org.jboss.messaging.core.server.MessageReference;
@@ -40,6 +43,7 @@
 import org.jboss.messaging.core.settings.HierarchicalRepository;
 import org.jboss.messaging.core.settings.impl.QueueSettings;
 import org.jboss.messaging.core.transaction.Transaction;
+import org.jboss.messaging.util.SimpleString;
 
 /**
  * A TransactionImpl
@@ -50,13 +54,20 @@
 {
    private static final Logger log = Logger.getLogger(TransactionImpl.class);
 
+   
    private final StorageManager storageManager;
 
    private final PostOffice postOffice;
+   
+   private final PagingManager pagingManager;
 
    private final List<MessageReference> refsToAdd = new ArrayList<MessageReference>();
 
    private final List<MessageReference> acknowledgements = new ArrayList<MessageReference>();
+   
+   private final List<ServerMessage> pagedMessages = new ArrayList<ServerMessage>();
+   
+   private PageTransactionInfoImpl pageTransaction;
 
    private final Xid xid;
 
@@ -72,8 +83,17 @@
                           final PostOffice postOffice)
    {
       this.storageManager = storageManager;
-
+      
       this.postOffice = postOffice;
+      
+      if (postOffice == null)
+      {
+         pagingManager = null;
+      }
+      else
+      {
+         this.pagingManager = postOffice.getPagingManager();
+      }
 
       this.xid = null;
 
@@ -87,6 +107,16 @@
 
       this.postOffice = postOffice;
 
+      if (postOffice == null)
+      {
+         pagingManager = null;
+      }
+      else
+      {
+         this.pagingManager = postOffice.getPagingManager();
+      }
+
+
       this.xid = xid;
 
       this.id = storageManager.generateTransactionID();
@@ -106,17 +136,15 @@
       {
          throw new IllegalStateException("Transaction is in invalid state " + state);
       }
-
-      List<MessageReference> refs = postOffice.route(message);
-
-      refsToAdd.addAll(refs);
-
-      if (message.getDurableRefCount() != 0)
+      
+      if (pagingManager.isPaging(message.getDestination()))
       {
-         storageManager.storeMessageTransactional(id, message);
-
-         containsPersistent = true;
+         pagedMessages.add(message);
       }
+      else
+      {
+         route(message);
+      }
    }
 
    public void addAcknowledgement(final MessageReference acknowledgement)
@@ -130,6 +158,14 @@
       acknowledgements.add(acknowledgement);
 
       ServerMessage message = acknowledgement.getMessage();
+      
+      if (message.decrementRefCount() == 0)
+      {
+         if (pagingManager != null)
+         {
+            pagingManager.messageDone(message);
+         }
+      }
 
       if (message.isDurable())
       {
@@ -177,6 +213,8 @@
          throw new IllegalStateException("Cannot prepare non XA transaction");
       }
 
+      pageMessages();
+      
       if (containsPersistent)
       {
          storageManager.prepare(id);
@@ -213,6 +251,12 @@
             throw new IllegalStateException("Transaction is in invalid state " + state);
          }
       }
+      
+      
+      if (state != State.PREPARED)
+      {
+         pageMessages();
+      }
 
       if (containsPersistent)
       {
@@ -224,6 +268,13 @@
          ref.getQueue().addLast(ref);
       }
 
+      // If part of the transaction goes to the queue, and part goes to paging, we can't let depage start for the transaction until all the messages were added to the queue
+      // or else we could deliver the messages out of order
+      if (pageTransaction != null)
+      {
+         pageTransaction.complete();
+      }
+
       for (MessageReference reference : acknowledgements)
       {
          reference.getQueue().referenceAcknowledged(reference);
@@ -255,7 +306,7 @@
       {
          storageManager.rollback(id);
       }
-
+      
       Map<Queue, LinkedList<MessageReference>> queueMap = new HashMap<Queue, LinkedList<MessageReference>>();
 
       // We sort into lists - one for each queue involved.
@@ -268,10 +319,11 @@
 
          ServerMessage message = ref.getMessage();
 
-         if (message.isDurable() && queue.isDurable())
+         
+         // Putting back the size on pagingManager, and reverting the counters
+         if (message.incrementReference(message.isDurable() && queue.isDurable()) == 1)
          {
-            // Reverse the decrements we did in the tx
-            message.incrementDurableRefCount();
+            pagingManager.addSize(message);
          }
 
          LinkedList<MessageReference> list = queueMap.get(queue);
@@ -360,10 +412,83 @@
    // Private
    // -------------------------------------------------------------------
 
+   private void route(final ServerMessage message) throws Exception
+   {
+      // We only set the messageID after we are sure the message is not being paged
+      // Paged messages won't have an ID until they are depaged 
+      if (message.getMessageID() == 0l)
+      {
+         message.setMessageID(storageManager.generateMessageID());
+      }
+
+      List<MessageReference> refs = postOffice.route(message);
+
+      refsToAdd.addAll(refs);
+
+      if (message.getDurableRefCount() != 0)
+      {
+         storageManager.storeMessageTransactional(id, message);
+
+         containsPersistent = true;
+      }
+   }
+
+   private void pageMessages() throws Exception
+   {
+      HashSet<SimpleString> pagedDestinationsToSync = new HashSet<SimpleString>();
+
+      boolean pagingPersistent = false;
+
+      if (pagedMessages.size() != 0)
+      {
+         if (pageTransaction == null)
+         {
+            pageTransaction = new PageTransactionInfoImpl(this.id);
+            // To avoid a race condition where depage happens before the transaction is completed, we need to inform the pager about this transaction is being processed 
+            pagingManager.addTransaction(pageTransaction);
+         }
+      }
+
+      
+      for (ServerMessage message: pagedMessages)
+      {
+       
+         // http://wiki.jboss.org/auth/wiki/JBossMessaging2Paging
+         // Explained under Transaction On Paging. (This is the item B)
+         if (pagingManager.page(message, id))
+         {
+            if (message.isDurable())
+            {
+               // We only create pageTransactions if using persistent messages
+               pageTransaction.increment();
+               pagingPersistent = true;
+               pagedDestinationsToSync.add(message.getDestination());
+            }
+         }
+         else
+         {
+            // This could happen when the PageStore left the pageState 
+            route(message);
+         }
+      }
+      
+      if (pagingPersistent)
+      {
+         containsPersistent = true;
+         if (pagedDestinationsToSync.size() > 0)
+         {
+            pagingManager.sync(pagedDestinationsToSync);
+            storageManager.storePageTransaction(id, pageTransaction);
+         }
+      }
+   }
+
    private void clear()
    {
       refsToAdd.clear();
 
       acknowledgements.clear();
+      
+      pagedMessages.clear();
    }
 }

Modified: trunk/src/main/org/jboss/messaging/jms/server/management/impl/JMSQueueControl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/jms/server/management/impl/JMSQueueControl.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/jms/server/management/impl/JMSQueueControl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -151,7 +151,7 @@
 
    public int getMaxSizeBytes()
    {
-      return coreQueue.getMaxSizeBytes();
+      return coreQueue.getSettings().getMaxSizeBytes();
    }
 
    public long getScheduledCount()

Modified: trunk/src/main/org/jboss/messaging/jms/server/management/impl/TopicControl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/jms/server/management/impl/TopicControl.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/src/main/org/jboss/messaging/jms/server/management/impl/TopicControl.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -41,6 +41,7 @@
 import org.jboss.messaging.core.server.MessageReference;
 import org.jboss.messaging.core.server.Queue;
 import org.jboss.messaging.core.server.ServerMessage;
+import org.jboss.messaging.core.settings.impl.QueueSettings;
 import org.jboss.messaging.jms.JBossTopic;
 import org.jboss.messaging.jms.server.management.JMSMessageInfo;
 import org.jboss.messaging.jms.server.management.SubscriptionInfo;
@@ -245,11 +246,13 @@
             subName = pair.b;
          }
 
+         QueueSettings queueSettings = queue.getSettings();
+         
          String filter = queue.getFilter() != null ? queue.getFilter()
                .getFilterString().toString() : null;
          SubscriptionInfo info = new SubscriptionInfo(queue.getName().toString(),
                clientID, subName, queue.isDurable(), filter, queue
-                     .getMessageCount(), queue.getMaxSizeBytes());
+                     .getMessageCount(), queueSettings.getMaxSizeBytes());
          subInfos.add(info);
       }
       return (SubscriptionInfo[]) subInfos.toArray(new SubscriptionInfo[subInfos

Modified: trunk/tests/jms-tests/src/org/jboss/test/messaging/jms/QueueRequestorTest.java
===================================================================
--- trunk/tests/jms-tests/src/org/jboss/test/messaging/jms/QueueRequestorTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/jms-tests/src/org/jboss/test/messaging/jms/QueueRequestorTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -21,10 +21,14 @@
   */
 package org.jboss.test.messaging.jms;
 
+import javax.jms.Connection;
+import javax.jms.DeliveryMode;
 import javax.jms.Destination;
 import javax.jms.JMSException;
 import javax.jms.Message;
+import javax.jms.MessageConsumer;
 import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
 import javax.jms.QueueConnection;
 import javax.jms.QueueReceiver;
 import javax.jms.QueueRequestor;
@@ -92,8 +96,9 @@
 	     if (conn1 != null) conn1.close();
 	     if (conn2 != null) conn2.close();
       }      
-   }   
+   }  
    
+   
    // Package protected ---------------------------------------------
    
    // Protected -----------------------------------------------------

Added: trunk/tests/src/org/jboss/messaging/tests/integration/paging/PagingIntegrationTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/integration/paging/PagingIntegrationTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/integration/paging/PagingIntegrationTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,88 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.tests.integration.paging;
+
+import java.io.File;
+
+import org.jboss.messaging.core.asyncio.impl.AsynchronousFileImpl;
+import org.jboss.messaging.core.journal.impl.AIOSequentialFileFactory;
+import org.jboss.messaging.core.journal.impl.NIOSequentialFileFactory;
+import org.jboss.messaging.tests.unit.core.paging.impl.PageImplTestBase;
+
+public class PagingIntegrationTest extends PageImplTestBase
+{
+   
+   // Constants -----------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+
+   protected String journalDir = System.getProperty("java.io.tmpdir", "/tmp") +  "/journal-test";
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   // Public --------------------------------------------------------
+   
+   public void testPageWithAIO() throws Exception
+   {
+      if (!AsynchronousFileImpl.isLoaded())
+      {
+         fail(String.format("libAIO is not loaded on %s %s %s", 
+               System.getProperty("os.name"), 
+               System.getProperty("os.arch"), 
+               System.getProperty("os.version")));
+      }
+      testAdd(new AIOSequentialFileFactory(journalDir), 1000);
+   }
+   
+   public void testPageWithNIO() throws Exception
+   {
+      testAdd(new NIOSequentialFileFactory(journalDir), 1000);
+   }
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   @Override
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+      File fileJournalDir = new File(journalDir);
+      deleteDirectory(fileJournalDir);
+      fileJournalDir.mkdirs();
+   }
+   
+   protected void tearDown() throws Exception
+   {
+      super.tearDown();
+      deleteDirectory(new File(journalDir));
+   }
+
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------
+   
+}

Added: trunk/tests/src/org/jboss/messaging/tests/integration/paging/PagingManagerIntegrationTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/integration/paging/PagingManagerIntegrationTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/integration/paging/PagingManagerIntegrationTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,191 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.tests.integration.paging;
+
+import java.io.File;
+import java.nio.ByteBuffer;
+
+import org.jboss.messaging.core.paging.Page;
+import org.jboss.messaging.core.paging.PageMessage;
+import org.jboss.messaging.core.paging.PagingStore;
+import org.jboss.messaging.core.paging.impl.PageMessageImpl;
+import org.jboss.messaging.core.paging.impl.PagingManagerFactoryNIO;
+import org.jboss.messaging.core.paging.impl.PagingManagerImpl;
+import org.jboss.messaging.core.remoting.impl.ByteBufferWrapper;
+import org.jboss.messaging.core.server.ServerMessage;
+import org.jboss.messaging.core.server.impl.ServerMessageImpl;
+import org.jboss.messaging.core.settings.HierarchicalRepository;
+import org.jboss.messaging.core.settings.impl.HierarchicalObjectRepository;
+import org.jboss.messaging.core.settings.impl.QueueSettings;
+import org.jboss.messaging.tests.util.RandomUtil;
+import org.jboss.messaging.tests.util.UnitTestCase;
+import org.jboss.messaging.util.SimpleString;
+
+/**
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public class PagingManagerIntegrationTest extends UnitTestCase
+{
+   
+   // Constants -----------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+
+   protected String journalDir = System.getProperty("java.io.tmpdir", "/tmp") +  "/journal-test";
+  
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   // Public --------------------------------------------------------
+   
+   public void testPagingManagerNIO() throws Exception
+   {
+      HierarchicalRepository<QueueSettings> queueSettings = new HierarchicalObjectRepository<QueueSettings>();
+      queueSettings.setDefault(new QueueSettings());
+      
+      
+      PagingManagerImpl managerImpl = 
+         new PagingManagerImpl(new PagingManagerFactoryNIO(journalDir), null, queueSettings);
+      managerImpl.start();
+      
+      PagingStore store = managerImpl.getPageStore(new SimpleString("simple-test"));
+      
+      ServerMessage msg = createMessage(1l, new SimpleString("simple-test"), createRandomBuffer(10));
+      
+      assertFalse(store.page(new PageMessageImpl(msg)));
+      
+      store.startPaging();
+      
+      assertTrue(store.page(new PageMessageImpl(msg)));
+      
+      Page page = store.depage();
+      
+      page.open();
+      
+      PageMessage msgs[] = page.read();
+      
+      page.close();
+      
+      assertEquals(1, msgs.length);
+      
+      assertEqualsByteArrays(msg.getBody().array(), msgs[0].getMessage().getBody().array());
+      
+      assertTrue(store.isPaging());
+      
+      assertNull(store.depage());
+      
+      assertFalse(store.page(new PageMessageImpl(msg)));
+   }
+   
+   public void testPagingManagerAddressFull() throws Exception
+   {
+      HierarchicalRepository<QueueSettings> queueSettings = new HierarchicalObjectRepository<QueueSettings>();
+      queueSettings.setDefault(new QueueSettings());
+      
+      QueueSettings simpleTestSettings = new QueueSettings();
+      simpleTestSettings.setDropMessagesWhenFull(true);
+      simpleTestSettings.setMaxSizeBytes(150);
+      
+      queueSettings.addMatch("simple-test", simpleTestSettings);
+      
+      PagingManagerImpl managerImpl = 
+         new PagingManagerImpl(new PagingManagerFactoryNIO(journalDir), null, queueSettings);
+      managerImpl.start();
+      
+      ServerMessage msg = createMessage(1l, new SimpleString("simple-test"), createRandomBuffer(100));
+      
+      long currentSize = managerImpl.addSize(msg);
+      
+      assertTrue(currentSize > 0);
+      
+      assertEquals(currentSize, managerImpl.getPageStore(new SimpleString("simple-test")).getAddressSize());
+      
+      for (int i = 0; i < 10; i++)
+      {
+         assertTrue(managerImpl.addSize(msg) < 0);
+         
+         assertEquals(currentSize, managerImpl.getPageStore(new SimpleString("simple-test")).getAddressSize());
+      }
+      
+      managerImpl.messageDone(msg);
+      
+      assertTrue(managerImpl.addSize(msg) > 0);
+      
+      managerImpl.stop();
+   }
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   @Override
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+      recreateDirectory();
+   }
+
+   protected ServerMessage createMessage(long messageId, SimpleString destination, ByteBuffer buffer)
+   {
+      ServerMessage msg = new ServerMessageImpl((byte)1, true, 0,
+            System.currentTimeMillis(), (byte)0, new ByteBufferWrapper(buffer));
+      
+      msg.setMessageID((long)messageId);
+      
+      msg.setDestination(destination);
+      return msg;
+   }
+
+   protected ByteBuffer createRandomBuffer(int size)
+   {
+      ByteBuffer buffer = ByteBuffer.allocate(size);
+      
+      for (int j = 0; j < buffer.limit(); j++)
+      {
+         buffer.put(RandomUtil.randomByte());
+      }
+      return buffer;
+   }
+   
+   protected void tearDown() throws Exception
+   {
+      super.tearDown();
+      //deleteDirectory(new File(journalDir));
+   }
+   
+   // Private -------------------------------------------------------
+
+   private void recreateDirectory()
+   {
+      File fileJournalDir = new File(journalDir);
+      deleteDirectory(fileJournalDir);
+      fileJournalDir.mkdirs();
+   }
+
+   
+   // Inner classes -------------------------------------------------
+   
+}

Added: trunk/tests/src/org/jboss/messaging/tests/integration/paging/PagingStoreIntegrationTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/integration/paging/PagingStoreIntegrationTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/integration/paging/PagingStoreIntegrationTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,100 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.tests.integration.paging;
+
+import java.io.File;
+
+import org.jboss.messaging.core.asyncio.impl.AsynchronousFileImpl;
+import org.jboss.messaging.core.journal.impl.AIOSequentialFileFactory;
+import org.jboss.messaging.core.journal.impl.NIOSequentialFileFactory;
+import org.jboss.messaging.tests.unit.core.paging.impl.PagingStoreTestBase;
+
+public class PagingStoreIntegrationTest extends PagingStoreTestBase
+{
+   // Constants -----------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+
+   protected String journalDir = System.getProperty("java.io.tmpdir", "/tmp") +  "/journal-test";
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   // Public --------------------------------------------------------
+   
+   public void testPageStoreWithAIO() throws Exception
+   {
+      if (!AsynchronousFileImpl.isLoaded())
+      {
+         fail(String.format("libAIO is not loaded on %s %s %s", 
+               System.getProperty("os.name"), 
+               System.getProperty("os.arch"), 
+               System.getProperty("os.version")));
+      }
+      testConcurrentPaging(new AIOSequentialFileFactory(journalDir), 10);
+   }
+   
+   public void testPageWithNIO() throws Exception
+   {
+      // This integration test could fail 1 in 100 due to race conditions.
+      for (int i = 0; i < 100; i++)
+      {
+         recreateDirectory();
+         System.out.println("Test " + i);
+         testConcurrentPaging(new NIOSequentialFileFactory(journalDir), 1);
+      }
+   }
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   @Override
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+      recreateDirectory();
+   }
+
+   
+   protected void tearDown() throws Exception
+   {
+      super.tearDown();
+      //deleteDirectory(new File(journalDir));
+   }
+
+   // Private -------------------------------------------------------
+
+   private void recreateDirectory()
+   {
+      File fileJournalDir = new File(journalDir);
+      deleteDirectory(fileJournalDir);
+      fileJournalDir.mkdirs();
+   }
+
+   // Inner classes -------------------------------------------------
+   
+   
+}

Modified: trunk/tests/src/org/jboss/messaging/tests/performance/journal/JournalImplTestUnit.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/performance/journal/JournalImplTestUnit.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/performance/journal/JournalImplTestUnit.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -201,7 +201,7 @@
    {
       Journal journal =
          new JournalImpl(10 * 1024 * 1024, 10, true, true, getFileFactory(),
-               "jbm-data", "jbm", 5000);
+               "jbm-data", "jbm", 5000, 0);
       
       journal.start();
       
@@ -263,7 +263,7 @@
 
       Journal journal =
          new JournalImpl(10 * 1024 * 1024,  numFiles, true, true, getFileFactory(),
-               "jbm-data", "jbm", 5000);
+               "jbm-data", "jbm", 5000, 0);
       
       journal.start();
       
@@ -289,7 +289,7 @@
       
       journal =
          new JournalImpl(10 * 1024 * 1024,  numFiles, true, true, getFileFactory(),
-               "jbm-data", "jbm", 5000);
+               "jbm-data", "jbm", 5000, 0);
       
       journal.start();
       journal.load(new ArrayList<RecordInfo>(), null);

Modified: trunk/tests/src/org/jboss/messaging/tests/performance/persistence/FakePostOffice.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/performance/persistence/FakePostOffice.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/performance/persistence/FakePostOffice.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -28,6 +28,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.jboss.messaging.core.filter.Filter;
+import org.jboss.messaging.core.paging.PagingManager;
 import org.jboss.messaging.core.postoffice.Binding;
 import org.jboss.messaging.core.postoffice.FlowController;
 import org.jboss.messaging.core.postoffice.PostOffice;
@@ -109,7 +110,6 @@
    public boolean removeDestination(SimpleString address, boolean temporary)
          throws Exception
    {
-      // TODO Auto-generated method stub
       return false;
    }
 
@@ -128,10 +128,8 @@
       return started;
    }
 
-   public List<org.jboss.messaging.core.server.MessageReference> route(
-         ServerMessage message) throws Exception
+   public List<org.jboss.messaging.core.server.MessageReference> route(ServerMessage message) throws Exception
    {
-      // TODO Auto-generated method stub
       return null;
    }
    
@@ -139,5 +137,10 @@
    {
    }
 
+   public PagingManager getPagingManager()
+   {
+      return null;
+   }
+
    
 }

Modified: trunk/tests/src/org/jboss/messaging/tests/stress/journal/AddAndRemoveStressTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/stress/journal/AddAndRemoveStressTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/stress/journal/AddAndRemoveStressTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -86,9 +86,8 @@
       file.mkdirs();
       
       SequentialFileFactory factory = new AIOSequentialFileFactory(journalDir);
-      JournalImpl impl = new JournalImpl(10*1024*1024, 60, true, false, factory, "jbm", "jbm", 1000);
+      JournalImpl impl = new JournalImpl(10*1024*1024, 60, true, false, factory, "jbm", "jbm", 1000, 0);
 
-      System.out.println("Starting journal");
       impl.start();
       
       impl.load(dummyLoader);
@@ -106,7 +105,7 @@
       
       
       factory = new AIOSequentialFileFactory(journalDir);
-      impl = new JournalImpl(10*1024*1024, 60, true, false, factory, "jbm", "jbm", 1000);
+      impl = new JournalImpl(10*1024*1024, 60, true, false, factory, "jbm", "jbm", 1000, 0);
 
       impl.start();
       
@@ -125,7 +124,7 @@
       impl.stop();
       
       factory = new AIOSequentialFileFactory(journalDir);
-      impl = new JournalImpl(10*1024*1024, 60, true, false, factory, "jbm", "jbm", 1000);
+      impl = new JournalImpl(10*1024*1024, 60, true, false, factory, "jbm", "jbm", 1000, 0);
 
       impl.start();
       
@@ -137,8 +136,6 @@
       impl.load(info, trans);
 
       
-      System.out.println("Info# - " + info.size());
-
       if (info.size() > 0)
       {
          System.out.println("Info ID: " + info.get(0).id);

Modified: trunk/tests/src/org/jboss/messaging/tests/stress/journal/remote/RemoteJournalAppender.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/stress/journal/remote/RemoteJournalAppender.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/stress/journal/remote/RemoteJournalAppender.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -142,7 +142,7 @@
    public static JournalImpl createJournal(String journalType, String journalDir)
    {
       JournalImpl journal = new JournalImpl(10485760, 2, true,
-            false, getFactory(journalType, journalDir), "journaltst", "tst", 5000);
+            false, getFactory(journalType, journalDir), "journaltst", "tst", 5000, 0);
       return journal;
    }
    

Modified: trunk/tests/src/org/jboss/messaging/tests/timing/core/server/impl/QueueImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/timing/core/server/impl/QueueImplTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/timing/core/server/impl/QueueImplTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -37,6 +37,7 @@
 import org.jboss.messaging.core.server.MessageReference;
 import org.jboss.messaging.core.server.Queue;
 import org.jboss.messaging.core.server.impl.QueueImpl;
+import org.jboss.messaging.core.settings.impl.QueueSettings;
 import org.jboss.messaging.tests.unit.core.server.impl.fakes.FakeConsumer;
 import org.jboss.messaging.tests.util.UnitTestCase;
 import org.jboss.messaging.util.SimpleString;
@@ -82,7 +83,7 @@
 
    public void testScheduledNoConsumer() throws Exception
    {
-      Queue queue = new QueueImpl(1, new SimpleString("queue1"), null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, new SimpleString("queue1"), null, false, true, new QueueSettings(), scheduledExecutor);
 
       //Send one scheduled
 
@@ -148,7 +149,7 @@
 
    private void testScheduled(boolean direct)
    {
-      Queue queue = new QueueImpl(1, new SimpleString("queue1"), null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, new SimpleString("queue1"), null, false, true, new QueueSettings(), scheduledExecutor);
 
       FakeConsumer consumer = null;
 
@@ -245,7 +246,7 @@
 
    public void testDeleteAllReferences() throws Exception
    {
-      Queue queue = new QueueImpl(1, new SimpleString("queue1"), null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, new SimpleString("queue1"), null, false, true, new QueueSettings(), scheduledExecutor);
 
       StorageManager storageManager = EasyMock.createStrictMock(StorageManager.class);
 
@@ -336,7 +337,7 @@
    public void testDeliveryScheduled() throws Exception
    {
       Consumer consumer = EasyMock.createStrictMock(Consumer.class);
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       MessageReference messageReference = generateReference(queue, 1);
       final CountDownLatch countDownLatch = new CountDownLatch(1);
       EasyMock.expect(consumer.handle(messageReference)).andAnswer(new IAnswer<HandleStatus>()
@@ -361,7 +362,7 @@
    public void testDeliveryScheduledBusyConsumer() throws Exception
    {
       Consumer consumer = EasyMock.createStrictMock(Consumer.class);
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       MessageReference messageReference = generateReference(queue, 1);
       final CountDownLatch countDownLatch = new CountDownLatch(1);
       EasyMock.expect(consumer.handle(messageReference)).andAnswer(new IAnswer<HandleStatus>()

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/AlignedJournalImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/AlignedJournalImplTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/AlignedJournalImplTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -162,7 +162,7 @@
          journalImpl = new JournalImpl(2000, 2,
             true, true,
             factory, 
-            "tt", "tt", 1000);
+            "tt", "tt", 1000, 0);
          fail ("Supposed to throw an exception");
       }
       catch (Exception ignored)
@@ -1163,7 +1163,7 @@
    {
 
       SequentialFileFactory factory = new FakeSequentialFileFactory(512, false);
-      JournalImpl impl = new JournalImpl(512 + 512 * 3, 20, true, false, factory, "jbm", "jbm", 1000);
+      JournalImpl impl = new JournalImpl(512 + 512 * 3, 20, true, false, factory, "jbm", "jbm", 1000, 0);
       
       impl.start();
       
@@ -1176,7 +1176,7 @@
 
       impl.stop();
 
-      impl = new JournalImpl(512 + 1024 + 512, 20, true, false, factory, "jbm", "jbm", 1000);
+      impl = new JournalImpl(512 + 1024 + 512, 20, true, false, factory, "jbm", "jbm", 1000, 0);
       impl.start();
       impl.load(dummyLoader);
       
@@ -1192,7 +1192,7 @@
       impl.stop();
       
       
-      impl = new JournalImpl(512 + 1024 + 512, 20, true, false, factory, "jbm", "jbm", 1000);
+      impl = new JournalImpl(512 + 1024 + 512, 20, true, false, factory, "jbm", "jbm", 1000, 0);
       impl.start();
       
       ArrayList<RecordInfo> info = new ArrayList<RecordInfo>();
@@ -1266,7 +1266,7 @@
       journalImpl = new JournalImpl(journalSize, numberOfMinimalFiles,
             true, true,
             factory, 
-            "tt", "tt", 1000);
+            "tt", "tt", 1000, 0);
       
       journalImpl.start();
       

Added: trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/CleanBufferTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/CleanBufferTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/CleanBufferTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,122 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.tests.unit.core.journal.impl;
+
+import java.nio.ByteBuffer;
+
+import org.jboss.messaging.core.asyncio.impl.AsynchronousFileImpl;
+import org.jboss.messaging.core.journal.SequentialFileFactory;
+import org.jboss.messaging.core.journal.impl.AIOSequentialFileFactory;
+import org.jboss.messaging.core.journal.impl.NIOSequentialFileFactory;
+import org.jboss.messaging.tests.unit.core.journal.impl.fakes.FakeSequentialFileFactory;
+import org.jboss.messaging.tests.util.UnitTestCase;
+
+/**
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public class CleanBufferTest extends UnitTestCase
+{
+   
+   // Constants -----------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   // Public --------------------------------------------------------
+   
+   
+   public void testCleanOnNIO()
+   {
+      SequentialFileFactory factory = new NIOSequentialFileFactory("Whatever");
+
+      testBuffer(factory);
+   }
+
+   public void testCleanOnAIO()
+   {
+      if (AsynchronousFileImpl.isLoaded())
+      {
+         SequentialFileFactory factory = new AIOSequentialFileFactory("Whatever");
+   
+         testBuffer(factory);
+      }
+   }
+
+   public void testCleanOnFake()
+   {
+      SequentialFileFactory factory = new FakeSequentialFileFactory();
+
+      testBuffer(factory);
+   }
+
+   private void testBuffer(SequentialFileFactory factory)
+   {
+      ByteBuffer buffer = factory.newBuffer(100);
+      for (byte b = 0; b < 100; b++)
+      {
+         buffer.put(b);
+      }
+      
+      buffer.rewind();
+      
+      for (byte b = 0; b < 100; b++)
+      {
+         assertEquals(b, buffer.get());
+      }
+      
+      
+
+      buffer.limit(10);
+      factory.clearBuffer(buffer);
+      buffer.limit(100);
+      
+      buffer.rewind();
+      
+      for (byte b = 0; b < 100; b++)
+      {
+         if (b < 10)
+         {
+            assertEquals(0, buffer.get());
+         }
+         else
+         {
+            assertEquals(b, buffer.get());
+         }
+      }
+   }
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------
+   
+}

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/EasyMockJournalTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/EasyMockJournalTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/EasyMockJournalTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -29,6 +29,7 @@
 import org.easymock.EasyMock;
 import org.easymock.IAnswer;
 import org.easymock.IArgumentMatcher;
+import org.jboss.messaging.core.journal.BufferCallback;
 import org.jboss.messaging.core.journal.SequentialFile;
 import org.jboss.messaging.core.journal.SequentialFileFactory;
 import org.jboss.messaging.core.journal.impl.JournalImpl;
@@ -399,7 +400,7 @@
       JournalImpl journalImpl = new JournalImpl(100 * 1024, 2,
             true, true,
             mockFactory,
-            "tt", "tt", 1000);
+            "tt", "tt", 1000, 0);
       
       journalImpl.start();
       
@@ -456,52 +457,30 @@
             });
       
       
-      EasyMock.expect(file1.getAlignment()).andStubReturn(1);
-      EasyMock.expect(file2.getAlignment()).andStubReturn(1);
-      
-   }
-   
-   
-   private ByteBuffer compareByteBuffer(final byte expectedArray[])
-   {
-      
-      EasyMock.reportMatcher(new IArgumentMatcher()
+      EasyMock.expect(mockFactory.calculateBlockSize(EasyMock.anyInt()))
+      .andStubAnswer(new IAnswer<Integer>()
       {
-
-         public void appendTo(StringBuffer buffer)
+         
+         public Integer answer() throws Throwable
          {
-            buffer.append("ByteArray");
+            return (Integer) EasyMock.getCurrentArguments()[0];
          }
-
-         public boolean matches(Object argument)
-         {
-            ByteBuffer buffer = (ByteBuffer) argument;
-            
-            buffer.rewind();
-            byte[] compareArray = new byte[buffer.limit()];
-            buffer.get(compareArray);
-            
-            if (compareArray.length != expectedArray.length)
-            {
-               return false;
-            }
-            
-            for (int i = 0; i < expectedArray.length; i++)
-            {
-               if (expectedArray[i] != compareArray[i])
-               {
-                  return false;
-               }
-            }
-            
-            return true;
-         }
-         
       });
       
-      return null;
-   }
+      file1.setBufferCallback(EasyMock.isA(BufferCallback.class));
+      EasyMock.expectLastCall().anyTimes();
+      
+      file2.setBufferCallback(EasyMock.isA(BufferCallback.class));
+      EasyMock.expectLastCall().anyTimes();
+      
+      
 
+      EasyMock.expect(file1.getAlignment()).andStubReturn(1);
+      EasyMock.expect(file2.getAlignment()).andStubReturn(1);
+      
+   }
+   
+   
    // Package protected ---------------------------------------------
    
    // Inner classes -------------------------------------------------

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/JournalAsyncTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/JournalAsyncTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/JournalAsyncTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -25,6 +25,7 @@
 
 import java.util.ArrayList;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import org.jboss.messaging.core.journal.PreparedTransactionInfo;
 import org.jboss.messaging.core.journal.RecordInfo;
@@ -83,6 +84,7 @@
             }
             catch (Exception e)
             {
+               e.printStackTrace();
                this.e = e;
             }
          }
@@ -90,9 +92,9 @@
       
       LocalThread t = new LocalThread();
       t.start();
+
+      assertTrue(latch.await(5, TimeUnit.SECONDS));
       
-      latch.await();
-      
       Thread.yield();
 
       assertTrue(t.isAlive());
@@ -331,7 +333,7 @@
       }
       
       journalImpl = new JournalImpl(journalSize, numberOfMinimalFiles, true,
-            true, factory, "tt", "tt", 1000);
+            true, factory, "tt", "tt", 1000, 0);
       
       journalImpl.start();
       

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/JournalImplTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/JournalImplTestBase.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/JournalImplTestBase.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -140,7 +140,7 @@
    
 	public void createJournal() throws Exception
 	{     
-		journal = new JournalImpl(fileSize, minFiles, sync, sync, fileFactory, filePrefix, fileExtension, maxAIO);
+		journal = new JournalImpl(fileSize, minFiles, sync, sync, fileFactory, filePrefix, fileExtension, maxAIO, 0);
 		journal.setAutoReclaim(false);
 	}
 	

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/JournalImplTestUnit.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/JournalImplTestUnit.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/JournalImplTestUnit.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -125,7 +125,7 @@
 	{
 		try
 		{
-			new JournalImpl(JournalImpl.MIN_FILE_SIZE - 1, 10, true, true, fileFactory, filePrefix, fileExtension, 1);
+			new JournalImpl(JournalImpl.MIN_FILE_SIZE - 1, 10, true, true, fileFactory, filePrefix, fileExtension, 1, 0);
 			
 			fail("Should throw exception");
 		}
@@ -136,7 +136,7 @@
 		
 		try
 		{
-			new JournalImpl(10 * 1024, 1, true, true, fileFactory, filePrefix, fileExtension, 1);
+			new JournalImpl(10 * 1024, 1, true, true, fileFactory, filePrefix, fileExtension, 1, 0);
 			
 			fail("Should throw exception");
 		}
@@ -147,7 +147,7 @@
 		
 		try
 		{
-			new JournalImpl(10 * 1024, 10, true, true, null, filePrefix, fileExtension, 1);
+			new JournalImpl(10 * 1024, 10, true, true, null, filePrefix, fileExtension, 1, 0);
 			
 			fail("Should throw exception");
 		}
@@ -158,7 +158,7 @@
 		
 		try
 		{
-			new JournalImpl(10 * 1024, 10, true, true, fileFactory, null, fileExtension, 1);
+			new JournalImpl(10 * 1024, 10, true, true, fileFactory, null, fileExtension, 1, 0);
 			
 			fail("Should throw exception");
 		}
@@ -169,7 +169,7 @@
 		
       try
       {
-         new JournalImpl(10 * 1024, 10, true, true, fileFactory, filePrefix, null, 1);
+         new JournalImpl(10 * 1024, 10, true, true, fileFactory, filePrefix, null, 1, 0);
          
          fail("Should throw exception");
       }
@@ -180,7 +180,7 @@
       
       try
       {
-         new JournalImpl(10 * 1024, 10, true, true, fileFactory, filePrefix, null, 0);
+         new JournalImpl(10 * 1024, 10, true, true, fileFactory, filePrefix, null, 0, 0);
          
          fail("Should throw exception");
       }

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/fakes/FakeSequentialFileFactory.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/fakes/FakeSequentialFileFactory.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/journal/impl/fakes/FakeSequentialFileFactory.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -28,6 +28,7 @@
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.jboss.messaging.core.journal.BufferCallback;
 import org.jboss.messaging.core.journal.IOCallback;
 import org.jboss.messaging.core.journal.SequentialFile;
 import org.jboss.messaging.core.journal.SequentialFileFactory;
@@ -101,6 +102,19 @@
       return sf;
    }
 
+   public void clearBuffer(final ByteBuffer buffer)
+   {
+      final int limit = buffer.limit();
+      buffer.rewind();
+      
+      for (int i = 0; i < limit; i++)
+      {
+         buffer.put((byte)0);
+      }
+      
+      buffer.rewind();
+   }
+   
    public List<String> listFiles(final String extension)
    {
       List<String> files = new ArrayList<String>();
@@ -140,6 +154,15 @@
       return ByteBuffer.allocateDirect(size);
    }
    
+   public int calculateBlockSize(int position)
+   {
+      int alignment = getAlignment();
+      
+      int pos = ((position / alignment) + (position % alignment != 0 ? 1 : 0)) * alignment;
+      
+      return pos;
+   }
+   
    public ByteBuffer wrapBuffer(byte[] bytes)
    {
       return ByteBuffer.wrap(bytes);
@@ -220,7 +243,7 @@
       final IOCallback callback;
       volatile boolean sendError;
       
-      CallbackRunnable(FakeSequentialFile file, ByteBuffer bytes, IOCallback callback)
+      CallbackRunnable(final FakeSequentialFile file, final ByteBuffer bytes, final IOCallback callback)
       {
          this.file = file;
          this.bytes = bytes;
@@ -236,8 +259,21 @@
          }
          else
          {
-            file.data.put(bytes);
-            if (callback!=null) callback.done();
+            try
+            {
+               file.data.put(bytes);
+               if (callback!=null) callback.done();
+               
+               if (file.bufferCallback != null)
+               {
+                  file.bufferCallback.bufferDone(bytes);
+               }
+            }
+            catch (Throwable e)
+            {
+               e.printStackTrace();
+               callback.onError(-1, e.getMessage());
+            }
          }
       }
 
@@ -260,7 +296,9 @@
       private final String fileName;
       
       private ByteBuffer data;
-      
+
+      private BufferCallback bufferCallback;
+
       public ByteBuffer getData()
       {
          return data;
@@ -311,8 +349,14 @@
       public synchronized void open(int currentMaxIO) throws Exception
       {
          open = true;
+         checkAndResize(0);
       }
 
+      public void setBufferCallback(BufferCallback callback)
+      {
+         this.bufferCallback = callback;
+      }
+
       public void fill(final int pos, final int size, final byte fillCharacter) throws Exception
       {     
          if (!open)
@@ -374,7 +418,7 @@
          return data.position();
       }
 
-      public int write(final ByteBuffer bytes, final IOCallback callback) throws Exception
+      public synchronized int write(final ByteBuffer bytes, final IOCallback callback) throws Exception
       {
          if (!open)
          {
@@ -387,7 +431,7 @@
          
          checkAlignment(bytes.limit());
          
-         checkAndResize(bytes.capacity() + position);
+         checkAndResize(bytes.limit() + position);
          
          CallbackRunnable action = new CallbackRunnable(this, bytes, callback);
          
@@ -409,6 +453,27 @@
          
       }
       
+      public void sync() throws Exception
+      {
+         if (supportsCallback)
+         {
+            throw new IllegalStateException("sync is not supported when supportsCallback=true");
+         }
+      }
+      
+      public long size() throws Exception
+      {
+         if (data == null)
+         {
+            return 0;
+         }
+         else
+         {
+            return data.limit();
+         }
+      }
+      
+      
       public int write(final ByteBuffer bytes, final boolean sync) throws Exception
       {
          return write(bytes, null);
@@ -459,6 +524,7 @@
       }
 
 
+
    }
 
 }

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/management/impl/QueueControlTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/management/impl/QueueControlTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/management/impl/QueueControlTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -203,19 +203,6 @@
       verifyMockedAttributes();
    }
 
-   public void testGetMaxSizeBytes() throws Exception
-   {
-      int size = randomInt();
-      expect(queue.getMaxSizeBytes()).andReturn(size);
-
-      replayMockedAttributes();
-
-      QueueControlMBean control = createControl();
-      assertEquals(size, control.getMaxSizeBytes());
-
-      verifyMockedAttributes();
-   }
-
    public void testGetSizeBytes() throws Exception
    {
       int size = randomInt();

Added: trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PageImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PageImplTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PageImplTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,69 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.tests.unit.core.paging.impl;
+
+import org.jboss.messaging.tests.unit.core.journal.impl.fakes.FakeSequentialFileFactory;
+
+
+/**
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public class PageImplTest extends PageImplTestBase
+{
+   
+   // Constants -----------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   // Public --------------------------------------------------------
+   
+   public void testPageFakeWithCallbacks() throws Exception
+   {
+      testAdd(new FakeSequentialFileFactory(512, true), 10);
+   }
+   
+   public void testPageFakeWithoutCallbacks() throws Exception
+   {
+      testAdd(new FakeSequentialFileFactory(1, false), 10);
+   }
+   
+   
+   
+    
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------
+   
+}

Added: trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PageImplTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PageImplTestBase.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PageImplTestBase.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,137 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.tests.unit.core.paging.impl;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+
+import org.jboss.messaging.core.journal.SequentialFile;
+import org.jboss.messaging.core.journal.SequentialFileFactory;
+import org.jboss.messaging.core.paging.PageMessage;
+import org.jboss.messaging.core.paging.impl.PageImpl;
+import org.jboss.messaging.core.paging.impl.PageMessageImpl;
+import org.jboss.messaging.core.remoting.impl.ByteBufferWrapper;
+import org.jboss.messaging.core.server.ServerMessage;
+import org.jboss.messaging.core.server.impl.ServerMessageImpl;
+import org.jboss.messaging.tests.util.RandomUtil;
+import org.jboss.messaging.tests.util.UnitTestCase;
+import org.jboss.messaging.util.SimpleString;
+
+/**
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public abstract class PageImplTestBase extends UnitTestCase
+{
+   
+   // Constants -----------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   // Public --------------------------------------------------------
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   /** Validate if everything we add is recovered */
+   protected void testAdd(SequentialFileFactory factory, int numberOfElements) throws Exception
+   {
+      
+      SequentialFile file = factory.createSequentialFile("00010.page", 1);
+      
+      PageImpl impl = new PageImpl(factory, file, 10);
+      
+      assertEquals(10, impl.getPageId());
+      
+      impl.open();
+
+      assertEquals(1, factory.listFiles("page").size());
+
+      ArrayList<ByteBuffer> buffers = new ArrayList<ByteBuffer>();
+      
+      SimpleString simpleDestination = new SimpleString("Test");
+      
+      for (int i = 0; i < numberOfElements; i++)
+      {
+         ByteBuffer buffer = ByteBuffer.allocate(10);
+         
+         for (int j = 0; j < buffer.limit(); j++)
+         {
+            buffer.put(RandomUtil.randomByte());
+         }
+         
+         buffers.add(buffer);
+
+         ServerMessage msg = new ServerMessageImpl((byte)1, true, 0,
+               System.currentTimeMillis(), (byte)0, new ByteBufferWrapper(buffer));
+         
+         msg.setMessageID((long)i);
+         
+         msg.setDestination(simpleDestination);
+         
+         impl.write(new PageMessageImpl(msg));
+         
+         assertEquals(i + 1, impl.getNumberOfMessages());
+      }
+      
+      impl.sync();
+      impl.close();
+      
+      file = factory.createSequentialFile("00010.page", 1);
+      file.open();
+      impl = new PageImpl(factory, file, 10);
+      
+      PageMessage msgs[] = impl.read();
+      
+      assertEquals(numberOfElements, msgs.length);
+
+      assertEquals(numberOfElements, impl.getNumberOfMessages());
+      
+      for (int i = 0; i < msgs.length; i++)
+      {
+         assertEquals((long)0, msgs[i].getMessage().getMessageID());
+         
+         assertEquals(simpleDestination, msgs[i].getMessage().getDestination());
+         
+         assertEqualsByteArrays(buffers.get(i).array(), msgs[i].getMessage().getBody().array());
+      }
+
+      impl.delete();
+      
+      
+      assertEquals(0, factory.listFiles(".page").size());
+      
+   }
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------
+   
+}

Added: trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PageManagerImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PageManagerImplTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PageManagerImplTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,199 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.tests.unit.core.paging.impl;
+
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+
+import org.easymock.EasyMock;
+import org.jboss.messaging.core.journal.SequentialFileFactory;
+import org.jboss.messaging.core.paging.PagingStore;
+import org.jboss.messaging.core.paging.PagingStoreFactory;
+import org.jboss.messaging.core.paging.impl.PagingManagerImpl;
+import org.jboss.messaging.core.paging.impl.PagingStoreImpl;
+import org.jboss.messaging.core.settings.HierarchicalRepository;
+import org.jboss.messaging.core.settings.impl.HierarchicalObjectRepository;
+import org.jboss.messaging.core.settings.impl.QueueSettings;
+import org.jboss.messaging.tests.util.UnitTestCase;
+import org.jboss.messaging.util.SimpleString;
+
+public class PageManagerImplTest extends UnitTestCase
+{
+   
+   // Constants -----------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   
+   private static HierarchicalRepository<QueueSettings> repoSettings = new HierarchicalObjectRepository<QueueSettings>();
+   static
+   {
+      repoSettings.setDefault(new QueueSettings());
+   }
+
+
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   // Public --------------------------------------------------------
+   
+   
+   public void testGetStore() throws Exception
+   {
+      HierarchicalRepository<QueueSettings> queueSettings = new HierarchicalObjectRepository<QueueSettings>();
+      queueSettings.setDefault(new QueueSettings());
+
+      PagingStoreFactory spi = EasyMock.createMock(PagingStoreFactory.class);
+      PagingManagerImpl manager = new PagingManagerImpl(spi, null, queueSettings);
+      
+      SimpleString destination = new SimpleString("some-destination");
+
+      try
+      {
+         manager.getPageStore(destination);
+         fail ("supposed to throw an exception");
+      }
+      catch (Exception ignored)
+      {
+      }
+      
+      manager.start();
+      
+      PagingStore store = EasyMock.createNiceMock(PagingStore.class);
+      
+      EasyMock.expect(spi.newStore(EasyMock.eq(destination), EasyMock.isA(QueueSettings.class))).andReturn(store);
+      
+      store.start();
+      
+      
+      EasyMock.replay(spi, store);
+      
+      assertEquals(store, manager.getPageStore(destination));
+      
+      EasyMock.verify(spi, store);
+      
+      EasyMock.reset(spi, store);
+      
+      EasyMock.replay(spi, store);
+
+      // it should use the cached store, so nothing else should be called on any SPI
+      assertEquals(store, manager.getPageStore(destination));
+      
+      EasyMock.verify(spi, store);
+      
+      EasyMock.reset(spi, store);
+      
+      store.stop();
+      
+      EasyMock.replay(spi, store);
+      
+      manager.stop();
+      
+      EasyMock.verify(spi, store);
+
+   }
+   
+   
+   public void testMultipleThreadsGetStore() throws Exception
+   {
+      PagingStoreFactory spi = EasyMock.createMock(PagingStoreFactory.class);
+      final PagingManagerImpl manager = new PagingManagerImpl(spi, null, repoSettings);
+      
+      final SimpleString destination = new SimpleString("some-destination");
+
+      final SequentialFileFactory factory = EasyMock.createNiceMock(SequentialFileFactory.class);
+      
+      EasyMock.expect(factory.listFiles(EasyMock.isA(String.class))).andStubReturn(new ArrayList<String>());
+      
+      PagingStoreImpl storeImpl = new PagingStoreImpl(factory, destination, new QueueSettings(), Executors.newSingleThreadExecutor());
+      
+      EasyMock.expect(spi.newStore(EasyMock.eq(destination), EasyMock.isA(QueueSettings.class))).andStubReturn(storeImpl);
+      
+      EasyMock.replay(spi, factory);
+      
+      manager.start();
+      
+      int NUMBER_OF_THREADS = 100;
+      
+      final CountDownLatch latchPositioned = new CountDownLatch(NUMBER_OF_THREADS);
+      final CountDownLatch latchReady = new CountDownLatch(1);
+      
+      class GetPageThread extends Thread
+      {
+         Exception  e;
+         
+         public void run()
+         {
+            try
+            {
+               latchPositioned.countDown();
+               latchReady.await();
+               manager.getPageStore(destination);
+               
+            }
+            catch (Exception e)
+            {
+               e.printStackTrace();
+               this.e = e;
+            }
+            
+         }
+      }
+      
+      GetPageThread threads[] = new GetPageThread[NUMBER_OF_THREADS];
+      for (int i = 0; i < NUMBER_OF_THREADS; i++)
+      {
+         threads[i] = new GetPageThread();
+         threads[i].start();
+      }
+      
+      latchPositioned.await();
+      latchReady.countDown();
+      
+      for (GetPageThread thread: threads)
+      {
+         thread.join();
+         if (thread.e != null)
+         {
+            throw thread.e;
+         }
+      }
+
+      EasyMock.verify(spi, factory);
+      
+   }
+   
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+   
+}

Added: trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PageTransactionImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PageTransactionImplTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PageTransactionImplTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,113 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.tests.unit.core.paging.impl;
+
+import java.nio.ByteBuffer;
+
+import org.jboss.messaging.core.paging.PageTransactionInfo;
+import org.jboss.messaging.core.paging.impl.PageTransactionInfoImpl;
+import org.jboss.messaging.core.remoting.spi.MessagingBuffer;
+import org.jboss.messaging.core.remoting.impl.ByteBufferWrapper;
+import org.jboss.messaging.tests.util.RandomUtil;
+import org.jboss.messaging.tests.util.UnitTestCase;
+
+/**
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public class PageTransactionImplTest extends UnitTestCase 
+{
+   
+   // Constants -----------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   // Public --------------------------------------------------------
+   
+   public void testAddAndRemoveMessages()
+   {
+      long id1 = RandomUtil.randomLong();
+      long id2 = RandomUtil.randomLong();
+      PageTransactionInfo trans = new PageTransactionInfoImpl(id2);
+      
+      trans.setRecordID(id1);
+      
+      // anything between 2 and 100
+      int nr1 = RandomUtil.randomPositiveInt()%98 + 2;
+
+      
+      for (int i = 0; i < nr1; i++)
+      {
+         trans.increment();
+      }
+      
+      
+      assertEquals(nr1, trans.getNumberOfMessages());
+      
+      ByteBuffer buffer = ByteBuffer.allocate(trans.getEncodeSize());
+      MessagingBuffer wrapper = new ByteBufferWrapper(buffer);
+      
+      trans.encode(wrapper);
+      wrapper.rewind();
+      
+      PageTransactionInfo trans2 = new PageTransactionInfoImpl(id1);
+      trans2.decode(wrapper);
+      
+      assertEquals(id2, trans2.getTransactionID());
+      
+      assertEquals(nr1, trans2.getNumberOfMessages());
+      
+      for (int i = 0; i < nr1; i++)
+      {
+         trans.decrement();
+      }
+      
+      assertEquals(0, trans.getNumberOfMessages());
+      
+      try
+      {
+         trans.decrement();
+         fail("Exception expected!");
+      }
+      catch (Throwable ignored)
+      {
+      }
+      
+      
+   }
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------
+   
+}

Added: trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PagingStoreImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PagingStoreImplTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PagingStoreImplTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,312 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.tests.unit.core.paging.impl;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.messaging.core.journal.SequentialFileFactory;
+import org.jboss.messaging.core.paging.Page;
+import org.jboss.messaging.core.paging.PageMessage;
+import org.jboss.messaging.core.paging.PagingStore;
+import org.jboss.messaging.core.paging.impl.PageMessageImpl;
+import org.jboss.messaging.core.paging.impl.PagingStoreImpl;
+import org.jboss.messaging.core.paging.impl.TestSupportPageStore;
+import org.jboss.messaging.core.settings.impl.QueueSettings;
+import org.jboss.messaging.tests.unit.core.journal.impl.fakes.FakeSequentialFileFactory;
+import org.jboss.messaging.util.SimpleString;
+
+/**
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public class PagingStoreImplTest extends PagingStoreTestBase
+{
+   
+   // Constants -----------------------------------------------------
+   
+   private final static SimpleString destinationTestName = new SimpleString("test");
+   
+   // Attributes ----------------------------------------------------
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   // Public --------------------------------------------------------
+ 
+   public void testDoubleStart() throws Exception
+   {
+      SequentialFileFactory factory = new FakeSequentialFileFactory();
+      
+      PagingStore storeImpl = new PagingStoreImpl(factory, destinationTestName, new QueueSettings(), executor);
+      
+      storeImpl.start();
+      
+      // this is not supposed to throw an exception.
+      // As you could have start being called twice as Stores are dynamically created, on a multi-thread environment
+      storeImpl.start();
+
+      storeImpl.stop();
+      
+   }
+   
+   public void testStore() throws Exception
+   {
+      SequentialFileFactory factory = new FakeSequentialFileFactory();
+      
+      PagingStore storeImpl = new PagingStoreImpl(factory, destinationTestName, new QueueSettings(), executor);
+      
+      storeImpl.start();
+      
+      assertEquals(0, storeImpl.getNumberOfPages());
+      
+      storeImpl.startPaging();
+
+      assertEquals(1, storeImpl.getNumberOfPages());
+      
+      List<ByteBuffer> buffers = new ArrayList<ByteBuffer>();
+
+      ByteBuffer buffer = createRandomBuffer(0, 10);
+      
+      buffers.add(buffer);
+      SimpleString destination = new SimpleString("test");
+
+      PageMessageImpl msg = createMessage(destination, buffer);
+      
+      assertTrue(storeImpl.isPaging());
+      
+      assertTrue(storeImpl.page(msg));
+      
+      assertEquals(1, storeImpl.getNumberOfPages());
+      
+      storeImpl.sync();
+      
+      storeImpl = new PagingStoreImpl(factory, destinationTestName, new QueueSettings(), executor);
+      
+      storeImpl.start();
+      
+      assertEquals(2, storeImpl.getNumberOfPages());
+      
+   }
+   
+   public void testDepageOnCurrentPage() throws Exception
+   {
+      SequentialFileFactory factory = new FakeSequentialFileFactory();
+      
+      PagingStore storeImpl = new PagingStoreImpl(factory, destinationTestName, new QueueSettings(), executor);
+      
+      storeImpl.start();
+      
+      assertEquals(0, storeImpl.getNumberOfPages());
+      
+      storeImpl.startPaging();
+      
+      List<ByteBuffer> buffers = new ArrayList<ByteBuffer>();
+      
+      SimpleString destination = new SimpleString("test");
+
+      for (int i = 0; i < 10; i++)
+      {
+
+         ByteBuffer buffer = createRandomBuffer(i+1l, 10);
+         
+         buffers.add(buffer);
+   
+         PageMessageImpl msg = createMessage(destination, buffer);
+
+         assertTrue(storeImpl.page(msg));
+      }
+      
+      
+      assertEquals(1, storeImpl.getNumberOfPages());
+      
+      storeImpl.sync();
+      
+      Page page = storeImpl.depage();
+      
+      page.open();
+      
+      PageMessage msg[] = page.read();
+      
+      assertEquals(10, msg.length);
+      assertEquals(1, storeImpl.getNumberOfPages());
+      
+      page = storeImpl.depage();
+      
+      assertNull(page);
+      
+      assertEquals(0, storeImpl.getNumberOfPages());
+      
+      for (int i = 0; i < 10; i++)
+      {
+         assertEquals(0, msg[i].getMessage().getMessageID());
+         assertEqualsByteArrays(buffers.get(i).array(), msg[i].getMessage().getBody().array());
+      }
+      
+   }
+   
+   public void testDepageMultiplePages() throws Exception
+   {
+      SequentialFileFactory factory = new FakeSequentialFileFactory();
+      
+      TestSupportPageStore storeImpl = new PagingStoreImpl(factory, destinationTestName, new QueueSettings(), executor);
+      
+      storeImpl.start();
+      
+      assertEquals(0, storeImpl.getNumberOfPages());
+      
+      storeImpl.startPaging();
+      
+      assertEquals(1, storeImpl.getNumberOfPages());
+      
+      List<ByteBuffer> buffers = new ArrayList<ByteBuffer>();
+      
+      SimpleString destination = new SimpleString("test");
+
+      for (int i = 0; i < 10; i++)
+      {
+
+         ByteBuffer buffer = createRandomBuffer(i+1l, 10);
+         
+         buffers.add(buffer);
+   
+         if (i == 5)
+         {
+            storeImpl.forceAnotherPage();
+         }
+         
+         
+         PageMessageImpl msg = createMessage(destination, buffer);
+
+         assertTrue(storeImpl.page(msg));
+      }
+      
+      
+      assertEquals(2, storeImpl.getNumberOfPages());
+      
+      storeImpl.sync();
+      
+      for (int pageNr = 0; pageNr < 2; pageNr++)
+      {
+         Page page = storeImpl.depage();
+         
+         page.open();
+         
+         PageMessage msg[] = page.read();
+         
+         page.close();
+
+         assertEquals(5, msg.length);
+         
+         for (int i = 0; i < 5; i++)
+         {
+            assertEquals(0, msg[i].getMessage().getMessageID());
+            assertEqualsByteArrays(buffers.get(pageNr*5 + i).array(), msg[i].getMessage().getBody().array());
+         }
+      }
+      
+      assertEquals(1, storeImpl.getNumberOfPages());
+      
+      assertTrue(storeImpl.isPaging());
+
+      PageMessageImpl msg = createMessage(destination, buffers.get(0));
+      
+      assertTrue(storeImpl.page(msg));
+      
+      Page newPage = storeImpl.depage();
+      
+      newPage.open();
+      
+      assertEquals(1, newPage.read().length);
+      
+      newPage.delete();
+      
+      assertEquals(1, storeImpl.getNumberOfPages());
+      
+      assertTrue(storeImpl.isPaging());
+      
+      assertNull(storeImpl.depage());      
+      
+      assertFalse(storeImpl.isPaging());
+      
+      assertFalse(storeImpl.page(msg));
+      
+      storeImpl.startPaging();
+
+      assertTrue(storeImpl.page(msg));
+      
+      Page page = storeImpl.depage();
+      
+      page.open();
+      
+      PageMessage msgs[] = page.read();
+      
+      assertEquals(1, msgs.length);
+      
+      assertEquals(0l, msgs[0].getMessage().getMessageID());
+      
+      assertEqualsByteArrays(buffers.get(0).array(), msgs[0].getMessage().getBody().array());
+      
+      assertEquals(1, storeImpl.getNumberOfPages());
+      
+      assertTrue(storeImpl.isPaging());
+      
+      assertNull(storeImpl.depage());
+      
+      assertEquals(0, storeImpl.getNumberOfPages());
+      
+      page.open();
+      
+      
+      
+   }
+   
+   
+   public void testConcurrentDepage() throws Exception
+   {
+      SequentialFileFactory factory = new FakeSequentialFileFactory(1, false);
+      
+      testConcurrentPaging(factory, 10);
+      
+   }
+   
+   // Protected ----------------------------------------------------
+   
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+   }
+   
+   protected void tearDown() throws Exception
+   {
+      super.tearDown();
+   }
+   
+   
+   // Inner classes -------------------------------------------------
+   
+}

Added: trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PagingStoreTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PagingStoreTestBase.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/paging/impl/PagingStoreTestBase.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -0,0 +1,345 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software 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.tests.unit.core.paging.impl;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.jboss.messaging.core.journal.SequentialFile;
+import org.jboss.messaging.core.journal.SequentialFileFactory;
+import org.jboss.messaging.core.paging.Page;
+import org.jboss.messaging.core.paging.PageMessage;
+import org.jboss.messaging.core.paging.impl.PageMessageImpl;
+import org.jboss.messaging.core.paging.impl.PagingStoreImpl;
+import org.jboss.messaging.core.paging.impl.TestSupportPageStore;
+import org.jboss.messaging.core.remoting.impl.ByteBufferWrapper;
+import org.jboss.messaging.core.server.ServerMessage;
+import org.jboss.messaging.core.server.impl.ServerMessageImpl;
+import org.jboss.messaging.core.settings.impl.QueueSettings;
+import org.jboss.messaging.tests.util.RandomUtil;
+import org.jboss.messaging.tests.util.UnitTestCase;
+import org.jboss.messaging.util.SimpleString;
+
+/**
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.com">Clebert Suconic</a>
+ *
+ */
+public abstract class PagingStoreTestBase extends UnitTestCase
+{
+   // Constants -----------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   protected ExecutorService executor;
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   // Public --------------------------------------------------------
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+      executor = Executors.newSingleThreadExecutor();
+   }
+   
+   protected void tearDown() throws Exception
+   {
+      super.tearDown();
+      executor.shutdown();
+   }
+   
+   protected void testConcurrentPaging(SequentialFileFactory factory, final int numberOfThreads) throws Exception,
+         InterruptedException
+   {
+      
+      final int MAX_SIZE = 1024 * 10;
+      
+      final AtomicLong messageIdGenerator = new AtomicLong(0);
+      
+      final AtomicInteger aliveProducers = new AtomicInteger(numberOfThreads);
+      
+      final CountDownLatch latchStart = new CountDownLatch(numberOfThreads);
+      
+      final ConcurrentHashMap<Long, PageMessageImpl> buffers = new ConcurrentHashMap<Long, PageMessageImpl>();
+      
+      final ArrayList<Page> readPages = new ArrayList<Page>();
+      
+      QueueSettings settings = new QueueSettings();
+      settings.setPageSizeBytes(MAX_SIZE);
+      
+      final TestSupportPageStore storeImpl = new PagingStoreImpl(factory, new SimpleString("test"), settings, executor);
+      
+      storeImpl.start();
+      
+      assertEquals(0, storeImpl.getNumberOfPages());
+      
+      storeImpl.startPaging();
+      
+      assertEquals(1, storeImpl.getNumberOfPages());
+      
+      
+   
+      
+      final SimpleString destination = new SimpleString("test");
+      
+      class ProducerThread extends Thread
+      {
+         
+         Exception e;
+         
+         public void run()
+         {
+            
+            try
+            {
+               boolean firstTime = true;
+               while (true)
+               {
+                  long id = messageIdGenerator.incrementAndGet();
+                  PageMessageImpl msg = createMessage(destination, createRandomBuffer(id, 5));
+                  if (storeImpl.page(msg))
+                  {
+                     buffers.put(id, msg);
+                  }
+                  else
+                  {
+                     break;
+                  }
+                  
+                  if (firstTime)
+                  {
+                     latchStart.countDown();
+                     firstTime = false;
+                  }
+               }
+            }
+            catch (Exception e)
+            {
+               e.printStackTrace();
+               this.e = e;
+            }
+            finally
+            {
+               aliveProducers.decrementAndGet();
+            }
+         }
+      }
+      
+      class ConsumerThread extends Thread
+      {
+         Exception e;
+         
+         public void run()
+         {
+            try
+            {
+               // Wait every producer to produce at least one message
+               latchStart.await();
+               while (aliveProducers.get() > 0)
+               {
+                  Page page = storeImpl.depage();
+                  if (page != null)
+                  {
+                     readPages.add(page);
+                  }
+               }
+            }
+            catch (Exception e)
+            {
+               e.printStackTrace();
+               this.e = e;
+            }
+         }
+      }
+      
+      ProducerThread producerThread[] = new ProducerThread[numberOfThreads];
+      
+      for (int i = 0; i < numberOfThreads; i++)
+      {
+         producerThread[i] = new ProducerThread();
+         producerThread[i].start();
+      }
+      
+      ConsumerThread consumer = new ConsumerThread();
+      consumer.start();
+      
+      for (int i = 0; i < numberOfThreads; i++)
+      {
+         producerThread[i].join();
+         if (producerThread[i].e != null)
+         {
+            throw producerThread[i].e;
+         }
+      }
+      
+      consumer.join();
+      
+      if (consumer.e != null)
+      {
+         throw consumer.e;
+      }
+   
+      System.out.println("Reading " + buffers.size() + " messages, " + readPages.size() + " pages");
+      
+      final ConcurrentHashMap<Long, PageMessage> buffers2 = new ConcurrentHashMap<Long, PageMessage>();
+      
+      for (Page page: readPages)
+      {
+         page.open();
+         PageMessage msgs[] = page.read();
+         page.close();
+         
+         for (PageMessage msg : msgs)
+         {
+            msg.getMessage().getBody().rewind();
+            long id = msg.getMessage().getBody().getLong();
+            msg.getMessage().getBody().rewind();
+            
+            PageMessageImpl msgWritten = buffers.remove(id);
+            buffers2.put(id, msg);
+            assertNotNull(msgWritten);
+            assertEquals (msg.getMessage().getDestination(), msgWritten.getMessage().getDestination());
+            assertEqualsByteArrays(msgWritten.getMessage().getBody().array(), msg.getMessage().getBody().array());
+         }
+      }
+      
+      assertEquals (0, buffers.size());
+      
+      List<String> files = factory.listFiles("page");
+      
+      assertTrue(files.size() != 0);
+      
+      for (String file: files)
+      {
+         SequentialFile fileTmp = factory.createSequentialFile(file, 1);
+         fileTmp.open();
+         assertTrue (fileTmp.size() + " <= " + MAX_SIZE, fileTmp.size() <= MAX_SIZE);
+         fileTmp.close();         
+      }
+      
+      TestSupportPageStore storeImpl2 = new PagingStoreImpl(factory, new SimpleString("test"), settings, executor);
+      storeImpl2.start();
+      
+      int numberOfPages = storeImpl2.getNumberOfPages();
+      assertTrue(numberOfPages != 0);
+      
+      storeImpl2.startPaging();
+      
+
+      
+      storeImpl2.startPaging();
+
+      
+      assertEquals(numberOfPages, storeImpl2.getNumberOfPages());
+      
+      long lastMessageId = messageIdGenerator.incrementAndGet();
+      PageMessage lastMsg = createMessage(destination, createRandomBuffer(lastMessageId, 5));
+      
+      storeImpl2.page(lastMsg);
+      buffers2.put(lastMessageId, lastMsg);
+      
+      Page lastPage = null;
+      while (true)
+      {
+         Page page = storeImpl2.depage();
+         if (page == null)
+         {
+            break;
+         }
+         
+         lastPage = page;
+         
+         page.open();
+         
+         PageMessage[] msgs = page.read();
+         
+         page.close();
+
+         for (PageMessage msg: msgs)
+         {
+            
+            msg.getMessage().getBody().rewind();
+            long id = msg.getMessage().getBody().getLong();
+            PageMessage msgWritten = buffers2.remove(id);
+            assertNotNull(msgWritten);
+            assertEquals (msg.getMessage().getDestination(), msgWritten.getMessage().getDestination());
+            assertEqualsByteArrays(msgWritten.getMessage().getBody().array(), msg.getMessage().getBody().array());
+         }
+      }
+      
+      
+      lastPage.open();
+      PageMessage lastMessages[] = lastPage.read();
+      lastPage.close();
+      assertEquals(1, lastMessages.length);
+      
+      lastMessages[0].getMessage().getBody().rewind();
+      assertEquals(lastMessages[0].getMessage().getBody().getLong(), lastMessageId);
+      assertEqualsByteArrays(lastMessages[0].getMessage().getBody().array(), lastMsg.getMessage().getBody().array());
+      
+      assertEquals(0, buffers2.size());
+      
+      
+   }
+
+   protected PageMessageImpl createMessage(SimpleString destination, ByteBuffer buffer)
+   {
+      ServerMessage msg = new ServerMessageImpl((byte)1, true, 0,
+            System.currentTimeMillis(), (byte)0, new ByteBufferWrapper(buffer));
+      
+      msg.setDestination(destination);
+      return new PageMessageImpl(msg);
+   }
+
+   protected ByteBuffer createRandomBuffer(long id, int size)
+   {
+      ByteBuffer buffer = ByteBuffer.allocate(size + 8);
+      
+      buffer.putLong(id);
+      
+      for (int j = 8; j < buffer.limit(); j++)
+      {
+         buffer.put(RandomUtil.randomByte());
+      }
+      return buffer;
+   }
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------
+   
+}

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/PostOfficeImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/PostOfficeImplTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/PostOfficeImplTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -32,6 +32,8 @@
 import org.jboss.messaging.core.exception.MessagingException;
 import org.jboss.messaging.core.filter.Filter;
 import org.jboss.messaging.core.management.ManagementService;
+import org.jboss.messaging.core.paging.PagingManager;
+import org.jboss.messaging.core.paging.PagingStore;
 import org.jboss.messaging.core.persistence.StorageManager;
 import org.jboss.messaging.core.postoffice.Binding;
 import org.jboss.messaging.core.postoffice.FlowController;
@@ -61,7 +63,10 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+      
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
+
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.replay(pm, qf);
@@ -75,7 +80,10 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
+      
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.replay(pm, qf);
@@ -103,7 +111,10 @@
       queue.setFlowController(null);
       EasyMock.expect(queue.getPersistenceID()).andStubReturn(1);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+      
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
+
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       EasyMock.expectLastCall().andAnswer(new LoadBindingsIAnswer(bindingArrayList, null));
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
@@ -146,17 +157,18 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       EasyMock.expectLastCall().andAnswer(new LoadBindingsIAnswer(bindingArrayList, null));
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
 
-      EasyMock.replay(pm, qf);
+      EasyMock.replay(pm, pgm, qf);
 
       postOffice.start();
 
-      EasyMock.verify(pm, qf);
+      EasyMock.verify(pm, pgm, qf);
 
       assertTrue(postOffice.isStarted());
       for (int i = 0; i < 100; i++)
@@ -188,11 +200,13 @@
       queue.setFlowController(null);
       EasyMock.expect(queue.getPersistenceID()).andStubReturn(1);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+      
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       EasyMock.expectLastCall().andAnswer(new LoadBindingsIAnswer(bindingArrayList, null));
 
-      EasyMock.replay(pm, qf, binding, binding2, queue);
+      EasyMock.replay(pm, pgm, qf, binding, binding2, queue);
 
       try
       {
@@ -203,7 +217,7 @@
       {
       }
 
-      EasyMock.verify(pm, qf, binding, binding2, queue);
+      EasyMock.verify(pm, pgm, qf, binding, binding2, queue);
 
       assertFalse(postOffice.isStarted());
    }
@@ -235,16 +249,18 @@
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       EasyMock.expectLastCall().andAnswer(new LoadBindingsIAnswer(bindingArrayList, null));
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
 
-      EasyMock.replay(pm, qf);
+      EasyMock.replay(pm, pgm, qf);
 
       postOffice.start();
 
-      EasyMock.verify(pm, qf);
+      EasyMock.verify(pm, pgm, qf);
 
       assertTrue(postOffice.isStarted());
       for (int i = 0; i < 1000; i++)
@@ -274,17 +290,21 @@
       queue.setFlowController((FlowController) EasyMock.anyObject());
       EasyMock.expect(queue.getPersistenceID()).andStubReturn(1);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+      PagingStore store = EasyMock.createNiceMock(PagingStore.class);
+      EasyMock.expect(pgm.getPageStore(address1)).andReturn(store);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       EasyMock.expectLastCall().andAnswer(new LoadBindingsIAnswer(bindingArrayList, dests));
       EasyMock.expect(pm.addDestination(address1)).andReturn(true);
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
 
-      EasyMock.replay(pm, qf, binding, queue);
+      EasyMock.replay(pm, qf, binding, queue, pgm, store);
 
       postOffice.start();
 
-      EasyMock.verify(pm, qf, binding, queue);
+      EasyMock.verify(pm, qf, binding, queue, pgm, store);
 
       assertTrue(postOffice.isStarted());
       assertEquals(postOffice.getBinding(queueName), binding);
@@ -298,7 +318,12 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+      
+      PagingStore pgstore = EasyMock.createNiceMock(PagingStore.class);
+      
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       ArrayList<Binding> bindingArrayList = new ArrayList<Binding>();
       List<SimpleString> dests = new ArrayList<SimpleString>();
       Binding[] bindings = new Binding[100];
@@ -312,6 +337,9 @@
          queues[i] = EasyMock.createStrictMock(Queue.class);
          addresses[i] = new SimpleString("testAddress" + i);
          queueNames[i] = new SimpleString("testQueueName" + i);
+         
+         EasyMock.expect(pgm.getPageStore(addresses[i])).andReturn(pgstore);
+         
          EasyMock.expect(bindings[i].getAddress()).andStubReturn(addresses[i]);
          EasyMock.expect(bindings[i].getQueue()).andStubReturn(queues[i]);
          EasyMock.expect(queues[i].getName()).andStubReturn(queueNames[i]);
@@ -330,11 +358,11 @@
       }
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
 
-      EasyMock.replay(pm, qf);
+      EasyMock.replay(pm, qf, pgm, pgstore);
 
       postOffice.start();
 
-      EasyMock.verify(pm, qf);
+      EasyMock.verify(pm, qf, pgm, pgstore);
 
       assertTrue(postOffice.isStarted());
       for (int i = 0; i < 100; i++)
@@ -351,8 +379,11 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+      PagingStore pgstore = EasyMock.createNiceMock(PagingStore.class);
+      
 
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       ArrayList<Binding> bindingArrayList = new ArrayList<Binding>();
       List<SimpleString> dests = new ArrayList<SimpleString>();
       Binding[] bindings = new Binding[100];
@@ -366,6 +397,7 @@
          queues[i] = EasyMock.createStrictMock(Queue.class);
          addresses[i] = new SimpleString("testAddress" + i);
          queueNames[i] = new SimpleString("testQueueName" + i);
+         EasyMock.expect(pgm.getPageStore(addresses[i])).andReturn(pgstore);
          EasyMock.expect(bindings[i].getAddress()).andStubReturn(addresses[i]);
          EasyMock.expect(bindings[i].getQueue()).andStubReturn(queues[i]);
          EasyMock.expect(queues[i].getName()).andStubReturn(queueNames[i]);
@@ -384,11 +416,11 @@
       }
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
 
-      EasyMock.replay(pm, qf);
+      EasyMock.replay(pm, qf, pgm, pgstore);
 
       postOffice.start();
       postOffice.stop();
-      EasyMock.verify(pm, qf);
+      EasyMock.verify(pm, qf, pgm, pgstore);
 
       assertFalse(postOffice.isStarted());
       for (int i = 0; i < 100; i++)
@@ -405,8 +437,10 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+      PagingStore pgstore = EasyMock.createNiceMock(PagingStore.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       ArrayList<Binding> bindingArrayList = new ArrayList<Binding>();
       List<SimpleString> dests = new ArrayList<SimpleString>();
       Binding[] bindings = new Binding[100];
@@ -420,6 +454,9 @@
          queues[i] = EasyMock.createStrictMock(Queue.class);
          addresses[i] = new SimpleString("testAddress" + i);
          queueNames[i] = new SimpleString("testQueueName" + i);
+         
+         EasyMock.expect(pgm.getPageStore(addresses[i])).andReturn(pgstore);
+         
          EasyMock.expect(bindings[i].getAddress()).andStubReturn(addresses[i]);
          EasyMock.expect(bindings[i].getQueue()).andStubReturn(queues[i]);
          EasyMock.expect(queues[i].getName()).andStubReturn(queueNames[i]);
@@ -438,11 +475,11 @@
       }
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
 
-      EasyMock.replay(pm, qf);
+      EasyMock.replay(pm, qf, pgm, pgstore);
 
       postOffice.start();
 
-      EasyMock.verify(pm, qf);
+      EasyMock.verify(pm, qf, pgm, pgstore);
 
       assertTrue(postOffice.isStarted());
       for (int i = 0; i < 100; i++)
@@ -458,8 +495,10 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+      PagingStore pgstore = EasyMock.createNiceMock(PagingStore.class);
 
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       ArrayList<Binding> bindingArrayList = new ArrayList<Binding>();
       List<SimpleString> dests = new ArrayList<SimpleString>();
       Binding[] bindings = new Binding[100];
@@ -473,6 +512,9 @@
          queues[i] = EasyMock.createStrictMock(Queue.class);
          addresses[i] = new SimpleString("testAddress" + i);
          queueNames[i] = new SimpleString("testQueueName" + i);
+         
+         EasyMock.expect(pgm.getPageStore(addresses[i])).andReturn(pgstore);
+         
          EasyMock.expect(bindings[i].getAddress()).andStubReturn(addresses[i]);
          EasyMock.expect(bindings[i].getQueue()).andStubReturn(queues[i]);
          EasyMock.expect(queues[i].getName()).andStubReturn(queueNames[i]);
@@ -491,11 +533,11 @@
       }
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
 
-      EasyMock.replay(pm, qf);
+      EasyMock.replay(pm, qf, pgm, pgstore);
 
       postOffice.start();
       Set<SimpleString> allDests = postOffice.listAllDestinations();
-      EasyMock.verify(pm, qf);
+      EasyMock.verify(pm, qf, pgm, pgstore);
 
       for (SimpleString dest : allDests)
       {
@@ -509,9 +551,10 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+ 
+      PostOffice po = new PostOfficeImpl(pm, pgm, qf, ms, false);
 
-      PostOffice po = new PostOfficeImpl(pm, qf, ms, false);
-
       final long id = 324;
       final SimpleString name = new SimpleString("wibb22");
       final Filter filter = EasyMock.createMock(Filter.class);
@@ -550,8 +593,9 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice po = new PostOfficeImpl(pm, qf, ms, false);
+      PostOffice po = new PostOfficeImpl(pm, pgm, qf, ms, false);
 
       final long id = 324;
       final SimpleString name = new SimpleString("wibb22");
@@ -600,8 +644,9 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = new FakeQueueFactory();
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
 
-      PostOffice po = new PostOfficeImpl(pm, qf, ms, false);
+      PostOffice po = new PostOfficeImpl(pm, pgm, qf, ms, false);
 
       final SimpleString condition1 = new SimpleString("queue.wibble");
 
@@ -687,7 +732,9 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.expect(pm.addDestination(address)).andReturn(true);
@@ -708,7 +755,9 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.expect(pm.addDestination(address)).andReturn(true);
@@ -735,7 +784,9 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.expect(pm.addDestination(address)).andReturn(true);
@@ -759,7 +810,9 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.expect(pm.addDestination(address)).andReturn(true);
@@ -798,7 +851,9 @@
       Filter filter = EasyMock.createStrictMock(Filter.class);
       Queue queue = EasyMock.createStrictMock(Queue.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.expect(qf.createQueue(-1, queueName, filter, true)).andReturn(queue);
@@ -826,7 +881,9 @@
       Queue queue2 = EasyMock.createStrictMock(Queue.class);
       Queue queue3 = EasyMock.createStrictMock(Queue.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.expect(qf.createQueue(-1, queueName, filter, true)).andReturn(queue);
@@ -864,7 +921,9 @@
       Filter filter = EasyMock.createStrictMock(Filter.class);
       Queue queue = EasyMock.createStrictMock(Queue.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.expect(qf.createQueue(-1, queueName, filter, false)).andReturn(queue);
@@ -891,7 +950,9 @@
       Queue queue2 = EasyMock.createStrictMock(Queue.class);
       Queue queue3 = EasyMock.createStrictMock(Queue.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.expect(qf.createQueue(-1, queueName, filter, false)).andReturn(queue);
@@ -926,7 +987,9 @@
       Filter filter = EasyMock.createStrictMock(Filter.class);
       Queue queue = EasyMock.createStrictMock(Queue.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.expect(qf.createQueue(-1, queueName, filter, true)).andReturn(queue);
@@ -961,7 +1024,9 @@
       Filter filter = EasyMock.createStrictMock(Filter.class);
       Queue queue = EasyMock.createStrictMock(Queue.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.expect(qf.createQueue(-1, queueName, filter, true)).andReturn(queue);
@@ -993,7 +1058,9 @@
       Queue queue2 = EasyMock.createStrictMock(Queue.class);
       Queue queue3 = EasyMock.createStrictMock(Queue.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.expect(qf.createQueue(-1, queueName, filter, true)).andReturn(queue);
@@ -1039,7 +1106,9 @@
       Filter filter = EasyMock.createStrictMock(Filter.class);
       Queue queue = EasyMock.createStrictMock(Queue.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.expect(qf.createQueue(-1, queueName, filter, false)).andReturn(queue);
@@ -1069,7 +1138,9 @@
       Queue queue2 = EasyMock.createStrictMock(Queue.class);
       Queue queue3 = EasyMock.createStrictMock(Queue.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.expect(qf.createQueue(-1, queueName, filter, false)).andReturn(queue);
@@ -1110,7 +1181,9 @@
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       Queue queue = EasyMock.createStrictMock(Queue.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.expect(queue.getName()).andStubReturn(queueName);
@@ -1137,7 +1210,9 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, true);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, true);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.expect(message.getDestination()).andStubReturn(new SimpleString("testtDestination"));
@@ -1163,13 +1238,17 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, false);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       EasyMock.expect(message.getDestination()).andStubReturn(new SimpleString("testtDestination"));
       EasyMock.replay(pm, qf, message);
+      
       postOffice.start();
       postOffice.route(message);
+      
       EasyMock.verify(pm, qf, message);
       assertTrue(postOffice.isStarted());
    }
@@ -1183,7 +1262,9 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, false);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       SimpleString address = new SimpleString("testtDestination");
@@ -1193,17 +1274,65 @@
       EasyMock.expect(queue.getFilter()).andStubReturn(null);
       queue.setBackup(false);
       queue.setFlowController((FlowController) EasyMock.anyObject());
+      
       EasyMock.expect(message.createReference(queue)).andReturn(messageReference);
+      
       EasyMock.replay(pm, qf, message, queue, messageReference);
+      
       postOffice.start();
       postOffice.addBinding(address, queueName, null, false);
+
       List<MessageReference> references = postOffice.route(message);
+      
       EasyMock.verify(pm, qf, message, queue, messageReference);
       assertTrue(postOffice.isStarted());
       assertEquals(1, references.size());
       assertEquals(messageReference, references.get(0));
    }
 
+   public void testRouteAddressFull() throws Exception
+   {
+      SimpleString queueName = new SimpleString("testQueueName");
+      
+      ServerMessage message = EasyMock.createStrictMock(ServerMessage.class);
+      
+      Queue queue = EasyMock.createStrictMock(Queue.class);
+      StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
+      QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
+      
+      ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
+      
+      PagingManager pgm = EasyMock.createMock(PagingManager.class);
+      pgm.setPostOffice(EasyMock.isA(PostOffice.class));
+      pgm.start();
+
+      EasyMock.expect(pgm.addSize(EasyMock.isA(ServerMessage.class))).andReturn(-1l);
+      
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false);
+      
+      pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
+      pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
+      
+      SimpleString address = new SimpleString("testtDestination");
+      EasyMock.expect(message.getDestination()).andStubReturn(address);
+      EasyMock.expect(qf.createQueue(-1, queueName, null, false)).andReturn(queue);
+      EasyMock.expect(queue.getName()).andStubReturn(queueName);
+      EasyMock.expect(queue.getFilter()).andStubReturn(null);
+      queue.setBackup(false);
+      queue.setFlowController((FlowController) EasyMock.anyObject());
+      
+      EasyMock.replay(pm, pgm, qf, message, queue);
+      
+      postOffice.start();
+      postOffice.addBinding(address, queueName, null, false);
+
+      List<MessageReference> references = postOffice.route(message);
+      
+      EasyMock.verify(pm, pgm, qf, message, queue);
+      assertTrue(postOffice.isStarted());
+      assertEquals(0, references.size());
+   }
+
    public void testPostOfficeRouteToSingleQueueValidFilter() throws Exception
    {
       SimpleString queueName = new SimpleString("testQueueName");
@@ -1214,7 +1343,9 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, false);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       SimpleString address = new SimpleString("testtDestination");
@@ -1246,7 +1377,9 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, false);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       SimpleString address = new SimpleString("testtDestination");
@@ -1281,7 +1414,9 @@
       StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
       QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
       ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-      PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, false);
+      PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+      PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false);
       pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
       pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
       SimpleString address = new SimpleString("testtDestination");
@@ -1335,7 +1470,9 @@
          StorageManager pm = EasyMock.createStrictMock(StorageManager.class);
          QueueFactory qf = EasyMock.createStrictMock(QueueFactory.class);
          ManagementService ms = EasyMock.createNiceMock(ManagementService.class);
-         PostOffice postOffice = new PostOfficeImpl(pm, qf, ms, false);
+         PagingManager pgm = EasyMock.createNiceMock(PagingManager.class);
+
+         PostOffice postOffice = new PostOfficeImpl(pm, pgm, qf, ms, false);
          pm.loadBindings(EasyMock.eq(qf), (List<Binding>) EasyMock.anyObject(), (List<SimpleString>) EasyMock.anyObject());
          pm.loadMessages(EasyMock.eq(postOffice), (Map<Long, Queue>) EasyMock.anyObject());
          SimpleString address = new SimpleString("testtDestination");

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/MessageReferenceImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/MessageReferenceImplTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/MessageReferenceImplTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -25,6 +25,7 @@
 
 import org.easymock.EasyMock;
 import org.jboss.messaging.core.message.impl.MessageImpl;
+import org.jboss.messaging.core.paging.PagingManager;
 import org.jboss.messaging.core.persistence.StorageManager;
 import org.jboss.messaging.core.postoffice.Binding;
 import org.jboss.messaging.core.postoffice.PostOffice;
@@ -123,82 +124,145 @@
       queueSettings.setMaxDeliveryAttempts(1);
       SimpleString dlqName = new SimpleString("testDLQ");
       queueSettings.setDLQ(dlqName);
+      
       Binding dlqBinding = EasyMock.createStrictMock(Binding.class);
       EasyMock.expect(dlqBinding.getAddress()).andReturn(dlqName);
+
       StorageManager sm = EasyMock.createNiceMock(StorageManager.class);
+      
       PostOffice po = EasyMock.createStrictMock(PostOffice.class);
+      PagingManager pm = EasyMock.createNiceMock(PagingManager.class);
+      EasyMock.expect(pm.page(EasyMock.isA(ServerMessage.class))).andStubReturn(false);
+      EasyMock.expect(po.getPagingManager()).andStubReturn(pm);
+      
+      
       HierarchicalRepository<QueueSettings> repos = EasyMock.createStrictMock(HierarchicalRepository.class);
-      ServerMessage serverMessage = EasyMock.createStrictMock(ServerMessage.class);
+      
+      ServerMessage serverMessage = EasyMock.createNiceMock(ServerMessage.class);
+      
       Queue queue = EasyMock.createStrictMock(Queue.class);
+      
       MessageReferenceImpl messageReference = new DummyMessageReference(serverMessage, queue);
       messageReference.setDeliveryCount(1);
+      
       SimpleString queueName = new SimpleString("queueName");
+      
       queue.referenceAcknowledged(messageReference);
+      
       EasyMock.expect(queue.getName()).andStubReturn(queueName);
+      
       EasyMock.expect(repos.getMatch(queueName.toString())).andStubReturn(queueSettings);
+      
       EasyMock.expect(serverMessage.isDurable()).andStubReturn(true);
+      
       EasyMock.expect(serverMessage.getMessageID()).andStubReturn(999l);
+      
       EasyMock.expect(queue.isDurable()).andStubReturn(true);
+      
       sm.updateDeliveryCount(messageReference);
+      
       EasyMock.expect(po.getBinding(dlqName)).andReturn(dlqBinding);
+      
       EasyMock.expect(serverMessage.copy()).andReturn(serverMessage);
+      
       EasyMock.expect(sm.generateMessageID()).andReturn(2l);
+      
       serverMessage.setMessageID(2);
+      
       EasyMock.expect(serverMessage.getDestination()).andReturn(queueName);
+      
       serverMessage.putStringProperty(MessageImpl.HDR_ORIGIN_QUEUE, queueName);
       serverMessage.setExpiration(0);
       serverMessage.setDestination(dlqName);
+      
       EasyMock.expect(po.route(serverMessage)).andReturn(new ArrayList<MessageReference>());
+      
       EasyMock.expect(serverMessage.getDurableRefCount()).andReturn(0);
+      EasyMock.expect(serverMessage.decrementRefCount()).andReturn(1);
       EasyMock.expect(serverMessage.decrementDurableRefCount()).andReturn(0);
+      
       EasyMock.expect(sm.generateTransactionID()).andReturn(1l);
-      EasyMock.replay(sm, po, repos, serverMessage, queue, dlqBinding);
+      
+      EasyMock.replay(sm, po, repos, serverMessage, queue, dlqBinding, pm);
+      
+      
       assertFalse(messageReference.cancel(sm, po, repos));
-      EasyMock.verify(sm, po, repos, serverMessage, queue, dlqBinding);
+      EasyMock.verify(sm, po, repos, serverMessage, queue, dlqBinding, pm);
    }
 
    public void testCancelToDLQDoesntExist() throws Exception
    {
       QueueSettings queueSettings = new QueueSettings();
       queueSettings.setMaxDeliveryAttempts(1);
+
       SimpleString dlqName = new SimpleString("testDLQ");
+      
       queueSettings.setDLQ(dlqName);
+      
       Binding dlqBinding = EasyMock.createStrictMock(Binding.class);
+      
       EasyMock.expect(dlqBinding.getAddress()).andReturn(dlqName);
+      
       StorageManager sm = EasyMock.createNiceMock(StorageManager.class);
+      
       PostOffice po = EasyMock.createStrictMock(PostOffice.class);
+      PagingManager pm = EasyMock.createNiceMock(PagingManager.class);
+      EasyMock.expect(pm.page(EasyMock.isA(ServerMessage.class))).andStubReturn(false);
+      EasyMock.expect(po.getPagingManager()).andStubReturn(pm);
+      EasyMock.expect(pm.isPaging(EasyMock.isA(SimpleString.class))).andStubReturn(false);
+      pm.messageDone(EasyMock.isA(ServerMessage.class));
+      EasyMock.expectLastCall().anyTimes();
+      
       HierarchicalRepository<QueueSettings> repos = EasyMock.createStrictMock(HierarchicalRepository.class);
-      ServerMessage serverMessage = EasyMock.createStrictMock(ServerMessage.class);
+      
+      ServerMessage serverMessage = EasyMock.createNiceMock(ServerMessage.class);
+      
       Queue queue = EasyMock.createStrictMock(Queue.class);
+      
       MessageReferenceImpl messageReference = new DummyMessageReference(serverMessage, queue);
       messageReference.setDeliveryCount(1);
+      
       SimpleString queueName = new SimpleString("queueName");
+      
       queue.referenceAcknowledged(messageReference);
+      
       EasyMock.expect(queue.getName()).andStubReturn(queueName);
+      
       EasyMock.expect(repos.getMatch(queueName.toString())).andStubReturn(queueSettings);
+      
       EasyMock.expect(serverMessage.isDurable()).andStubReturn(true);
       EasyMock.expect(serverMessage.getMessageID()).andStubReturn(999l);
+      
       EasyMock.expect(queue.isDurable()).andStubReturn(true);
+      
       sm.updateDeliveryCount(messageReference);
+      
       EasyMock.expect(po.getBinding(dlqName)).andReturn(null);
       EasyMock.expect(po.addBinding(dlqName, dlqName, null, true)).andReturn(dlqBinding);
+      
       EasyMock.expect(serverMessage.copy()).andReturn(serverMessage);
+      
       EasyMock.expect(sm.generateMessageID()).andReturn(2l);
+      
       serverMessage.setMessageID(2);
+      
       EasyMock.expect(serverMessage.getDestination()).andReturn(queueName);
       serverMessage.putStringProperty(MessageImpl.HDR_ORIGIN_QUEUE, queueName);
       serverMessage.setExpiration(0);
       serverMessage.setDestination(dlqName);
+      
       EasyMock.expect(po.route(serverMessage)).andReturn(new ArrayList<MessageReference>());
+      
       EasyMock.expect(serverMessage.getDurableRefCount()).andReturn(0);
       EasyMock.expect(serverMessage.decrementDurableRefCount()).andReturn(0);
+      
       EasyMock.expect(sm.generateTransactionID()).andReturn(1l);
       
-      EasyMock.replay(sm, po, repos, serverMessage, queue, dlqBinding);
+      EasyMock.replay(sm, po, repos, serverMessage, queue, dlqBinding, pm);
       
       assertFalse(messageReference.cancel(sm, po, repos));
       
-      EasyMock.verify(sm, po, repos, serverMessage, queue, dlqBinding);
+      EasyMock.verify(sm, po, repos, serverMessage, queue, dlqBinding, pm);
    }
 
    public void testExpire() throws Exception
@@ -208,7 +272,15 @@
       SimpleString dlqName = new SimpleString("testDLQ");
       queueSettings.setDLQ(dlqName);
       StorageManager sm = EasyMock.createNiceMock(StorageManager.class);
+      
       PostOffice po = EasyMock.createStrictMock(PostOffice.class);
+      PagingManager pm = EasyMock.createNiceMock(PagingManager.class);
+      EasyMock.expect(pm.page(EasyMock.isA(ServerMessage.class))).andStubReturn(false);
+      EasyMock.expect(po.getPagingManager()).andStubReturn(pm);
+      EasyMock.expect(pm.isPaging(EasyMock.isA(SimpleString.class))).andStubReturn(false);
+      pm.messageDone(EasyMock.isA(ServerMessage.class));
+      EasyMock.expectLastCall().anyTimes();
+
       HierarchicalRepository<QueueSettings> repos = EasyMock.createStrictMock(HierarchicalRepository.class);
       ServerMessage serverMessage = EasyMock.createStrictMock(ServerMessage.class);
       Queue queue = EasyMock.createStrictMock(Queue.class);
@@ -220,13 +292,14 @@
       EasyMock.expect(repos.getMatch(queueName.toString())).andStubReturn(queueSettings);
       EasyMock.expect(serverMessage.isDurable()).andStubReturn(true);
       EasyMock.expect(serverMessage.getMessageID()).andStubReturn(999l);
+      EasyMock.expect(serverMessage.decrementRefCount()).andReturn(1);
       EasyMock.expect(queue.isDurable()).andStubReturn(true);
       EasyMock.expect(serverMessage.decrementDurableRefCount()).andReturn(0);
       EasyMock.expect(sm.generateTransactionID()).andReturn(1l);
 
-      EasyMock.replay(sm, po, repos, serverMessage, queue);
+      EasyMock.replay(sm, po, repos, serverMessage, queue, pm);
       messageReference.expire(sm, po, repos);
-      EasyMock.verify(sm, po, repos, serverMessage, queue);
+      EasyMock.verify(sm, po, repos, serverMessage, queue, pm);
    }
 
    public void testExpireToQExists() throws Exception
@@ -237,9 +310,18 @@
       Binding expQBinding = EasyMock.createStrictMock(Binding.class);
       queueSettings.setExpiryQueue(expQName);
       StorageManager sm = EasyMock.createNiceMock(StorageManager.class);
+
       PostOffice po = EasyMock.createStrictMock(PostOffice.class);
+      PagingManager pm = EasyMock.createNiceMock(PagingManager.class);
+      EasyMock.expect(pm.page(EasyMock.isA(ServerMessage.class))).andStubReturn(false);
+      EasyMock.expect(po.getPagingManager()).andStubReturn(pm);
+      EasyMock.expect(pm.isPaging(EasyMock.isA(SimpleString.class))).andStubReturn(false);
+      pm.messageDone(EasyMock.isA(ServerMessage.class));
+      EasyMock.expectLastCall().anyTimes();
+      
       HierarchicalRepository<QueueSettings> repos = EasyMock.createStrictMock(HierarchicalRepository.class);
-      ServerMessage serverMessage = EasyMock.createStrictMock(ServerMessage.class);
+      
+      ServerMessage serverMessage = EasyMock.createNiceMock(ServerMessage.class);
       Queue queue = EasyMock.createStrictMock(Queue.class);
       MessageReferenceImpl messageReference = new DummyMessageReference(serverMessage, queue);
       messageReference.setDeliveryCount(1);
@@ -265,11 +347,11 @@
       EasyMock.expect(serverMessage.getDurableRefCount()).andReturn(0);
       EasyMock.expect(serverMessage.decrementDurableRefCount()).andReturn(0);
 
-      EasyMock.replay(sm, po, repos, serverMessage, queue, expQBinding);
+      EasyMock.replay(sm, po, repos, serverMessage, queue, expQBinding, pm);
       
       messageReference.expire(sm, po, repos);
 
-      EasyMock.verify(sm, po, repos, serverMessage, queue, expQBinding);
+      EasyMock.verify(sm, po, repos, serverMessage, queue, expQBinding, pm);
    }
 
    public void testExpireToQDoesntExist() throws Exception
@@ -280,9 +362,20 @@
       Binding expQBinding = EasyMock.createStrictMock(Binding.class);
       queueSettings.setExpiryQueue(expQName);
       StorageManager sm = EasyMock.createNiceMock(StorageManager.class);
+      
       PostOffice po = EasyMock.createStrictMock(PostOffice.class);
+      
+      PagingManager pm = EasyMock.createNiceMock(PagingManager.class);
+      EasyMock.expect(pm.page(EasyMock.isA(ServerMessage.class))).andStubReturn(false);
+      EasyMock.expect(po.getPagingManager()).andStubReturn(pm);
+      EasyMock.expect(pm.isPaging(EasyMock.isA(SimpleString.class))).andStubReturn(false);
+      pm.messageDone(EasyMock.isA(ServerMessage.class));
+      EasyMock.expectLastCall().anyTimes();
+      
       HierarchicalRepository<QueueSettings> repos = EasyMock.createStrictMock(HierarchicalRepository.class);
-      ServerMessage serverMessage = EasyMock.createStrictMock(ServerMessage.class);
+      
+      ServerMessage serverMessage = EasyMock.createNiceMock(ServerMessage.class);
+      
       Queue queue = EasyMock.createStrictMock(Queue.class);
       MessageReferenceImpl messageReference = new DummyMessageReference(serverMessage, queue);
       messageReference.setDeliveryCount(1);
@@ -309,11 +402,11 @@
       EasyMock.expect(serverMessage.getDurableRefCount()).andReturn(0);
       EasyMock.expect(serverMessage.decrementDurableRefCount()).andReturn(0);
 
-      EasyMock.replay(sm, po, repos, serverMessage, queue, expQBinding);
+      EasyMock.replay(sm, po, repos, serverMessage, queue, expQBinding, pm);
       
       messageReference.expire(sm, po, repos);
       
-      EasyMock.verify(sm, po, repos, serverMessage, queue, expQBinding);
+      EasyMock.verify(sm, po, repos, serverMessage, queue, expQBinding, pm);
    }
 
    public void testMove() throws Exception
@@ -328,10 +421,21 @@
       Binding toBinding = EasyMock.createStrictMock(Binding.class);
       Queue toQueue = EasyMock.createStrictMock(Queue.class);
       PostOffice postOffice = EasyMock.createMock(PostOffice.class);
+      
+      
+      PagingManager pm = EasyMock.createNiceMock(PagingManager.class);
+      EasyMock.expect(pm.page(EasyMock.isA(ServerMessage.class))).andStubReturn(false);
+      EasyMock.expect(postOffice.getPagingManager()).andStubReturn(pm);
+      EasyMock.expect(pm.isPaging(EasyMock.isA(SimpleString.class))).andStubReturn(false);
+      pm.messageDone(EasyMock.isA(ServerMessage.class));
+      EasyMock.expectLastCall().anyTimes();
+      
       StorageManager persistenceManager = EasyMock.createMock(StorageManager.class);
-      ServerMessage serverMessage = EasyMock.createStrictMock(ServerMessage.class);
+      ServerMessage serverMessage = EasyMock.createNiceMock(ServerMessage.class);
+      EasyMock.expect(serverMessage.getMessageID()).andStubReturn(1l);
       MessageReferenceImpl messageReference = new DummyMessageReference(serverMessage, queue);
-      ServerMessage copyMessage = EasyMock.createStrictMock(ServerMessage.class);
+      ServerMessage copyMessage = EasyMock.createNiceMock(ServerMessage.class);
+      EasyMock.expect(copyMessage.getMessageID()).andStubReturn(1l);
 
       EasyMock.expect(persistenceManager.generateTransactionID()).andReturn(tid);
       EasyMock.expect(serverMessage.copy()).andReturn(copyMessage);
@@ -348,11 +452,11 @@
       EasyMock.expect(serverMessage.getMessageID()).andReturn(messageID);
       queue.referenceAcknowledged(messageReference);
 
-      EasyMock.replay(queue, toBinding, toQueue, postOffice, persistenceManager, serverMessage, copyMessage);
+      EasyMock.replay(queue, toBinding, toQueue, postOffice, persistenceManager, serverMessage, copyMessage, pm);
       
       messageReference.move(toBinding, persistenceManager, postOffice);
       
-      EasyMock.verify(queue, toBinding, toQueue, postOffice, persistenceManager, serverMessage, copyMessage);
+      EasyMock.verify(queue, toBinding, toQueue, postOffice, persistenceManager, serverMessage, copyMessage, pm);
    }
    
    //we need to override the constructor for creation

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/QueueFactoryImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/QueueFactoryImplTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/QueueFactoryImplTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -55,7 +55,6 @@
       EasyMock.verify(scheduledExecutor, queueSettingsRepository);
       assertEquals(queue.getDistributionPolicy().getClass(), RoundRobinDistributionPolicy.class);
       assertEquals(queue.isClustered(), true);
-      assertEquals(queue.getMaxSizeBytes(), 9999);
       assertEquals(queue.getName(), qName);
       assertEquals(queue.getPersistenceID(), 123);
       assertEquals(queue.getFilter(), filter);
@@ -79,7 +78,6 @@
       EasyMock.verify(scheduledExecutor, queueSettingsRepository);
       assertEquals(queue.getDistributionPolicy().getClass(), RoundRobinDistributionPolicy.class);
       assertEquals(queue.isClustered(), false);
-      assertEquals(queue.getMaxSizeBytes(), 8888);
       assertEquals(queue.getName(), qName);
       assertEquals(queue.getPersistenceID(), 456);
       assertEquals(queue.getFilter(), null);

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/QueueImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/QueueImplTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/QueueImplTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -42,6 +42,7 @@
 
 import org.easymock.EasyMock;
 import org.jboss.messaging.core.filter.Filter;
+import org.jboss.messaging.core.paging.PagingManager;
 import org.jboss.messaging.core.persistence.StorageManager;
 import org.jboss.messaging.core.postoffice.Binding;
 import org.jboss.messaging.core.postoffice.PostOffice;
@@ -77,7 +78,7 @@
    {
       final long id = 123;
 
-      Queue queue = new QueueImpl(id, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(id, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       assertEquals(id, queue.getPersistenceID());
 
@@ -92,46 +93,33 @@
    {
       final SimpleString name = new SimpleString("oobblle");
 
-      Queue queue = new QueueImpl(1, name, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, name, null, false, true, new QueueSettings(), scheduledExecutor);
 
       assertEquals(name, queue.getName());
    }
 
    public void testClustered()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       assertFalse(queue.isClustered());
 
-      queue = new QueueImpl(1, queue1, null, true, true, -1, scheduledExecutor);
+      queue = new QueueImpl(1, queue1, null, true, true, new QueueSettings(), scheduledExecutor);
 
       assertTrue(queue.isClustered());
    }
 
    public void testDurable()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, false, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, false, new QueueSettings(), scheduledExecutor);
 
       assertFalse(queue.isDurable());
 
-      queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       assertTrue(queue.isDurable());
    }
 
-   public void testGetMaxSizeBytes()
-   {
-      final int maxSize = 123456;
-
-      final int id = 123;
-
-      Queue queue = new QueueImpl(id, queue1, null, false, true, maxSize, scheduledExecutor);
-
-      assertEquals(id, queue.getPersistenceID());
-
-      assertEquals(maxSize, queue.getMaxSizeBytes());
-   }
-
    public void testAddRemoveConsumer() throws Exception
    {
       Consumer cons1 = new FakeConsumer();
@@ -140,7 +128,7 @@
 
       Consumer cons3 = new FakeConsumer();
 
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       assertEquals(0, queue.getConsumerCount());
 
@@ -181,7 +169,7 @@
 
    public void testGetSetDistributionPolicy()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       assertNotNull(queue.getDistributionPolicy());
 
@@ -196,30 +184,23 @@
 
    public void testGetFilter()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       assertNull(queue.getFilter());
 
       Filter filter = createMock(Filter.class);
       replay(filter);
 
-      queue = new QueueImpl(1, queue1, filter, false, true, -1, scheduledExecutor);
+      queue = new QueueImpl(1, queue1, filter, false, true, new QueueSettings(), scheduledExecutor);
 
       assertEquals(filter, queue.getFilter());
       
       verify(filter);
    }
 
-   public void testDefaultMaxSize()
-   {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
-
-      assertEquals(-1, queue.getMaxSizeBytes());
-   }
-
    public void testSimpleAddLast()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       final int numMessages = 10;
 
@@ -238,7 +219,7 @@
 
    public void testSimpleDirectDelivery()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       FakeConsumer consumer = new FakeConsumer();
 
@@ -266,7 +247,7 @@
 
    public void testSimpleNonDirectDelivery()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       final int numMessages = 10;
 
@@ -304,7 +285,7 @@
 
    public void testBusyConsumer()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       FakeConsumer consumer = new FakeConsumer();
 
@@ -348,7 +329,7 @@
 
    public void testBusyConsumerThenAddMoreMessages()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       FakeConsumer consumer = new FakeConsumer();
 
@@ -415,7 +396,7 @@
 
    public void testAddFirstAddLast()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       final int numMessages = 10;
 
@@ -470,7 +451,7 @@
 
    public void testChangeConsumersAndDeliver() throws Exception
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       final int numMessages = 10;
 
@@ -624,7 +605,7 @@
 
    public void testConsumerReturningNull()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       class NullConsumer implements Consumer
       {
@@ -652,7 +633,7 @@
 
    public void testRoundRobinWithQueueing()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       assertTrue(queue.getDistributionPolicy() instanceof RoundRobinDistributionPolicy);
 
@@ -697,7 +678,7 @@
 
    public void testRoundRobinDirect()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       assertTrue(queue.getDistributionPolicy() instanceof RoundRobinDistributionPolicy);
 
@@ -740,7 +721,7 @@
 
    public void testDeleteAllReferences() throws Exception
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       StorageManager storageManager = EasyMock.createStrictMock(StorageManager.class);
 
@@ -822,64 +803,9 @@
       assertTrue(consumer.getReferences().isEmpty());
    }
 
-   public void testMaxSize()
-   {
-      final int maxSize = 10 * 1024;
-
-      Queue queue = new QueueImpl(1, queue1, null, false, true, maxSize, scheduledExecutor);
-
-      List<MessageReference> refs = new ArrayList<MessageReference>();
-
-      int size = 0;
-
-      int i = 0;
-      while (true)
-      {
-         MessageReference ref = generateReference(queue, i++);
-
-         if (size + ref.getMessage().getEncodeSize() > maxSize)
-         {
-            break;
-         }
-
-         size += ref.getMessage().getEncodeSize();
-
-         refs.add(ref);
-
-         assertEquals(HandleStatus.HANDLED, queue.addLast(ref));
-      }
-
-      assertEquals(maxSize, queue.getMaxSizeBytes());
-      assertEquals(size, queue.getSizeBytes());
-
-      //Try to add more
-
-      for (int j = 0; j < 10; j++)
-      {
-         MessageReference ref = generateReference(queue, j);
-
-         assertEquals(HandleStatus.BUSY, queue.addLast(ref));
-      }
-
-      assertEquals(maxSize, queue.getMaxSizeBytes());
-      assertEquals(size, queue.getSizeBytes());
-
-      // Try to add at front too
-
-      for (int j = 0; j < 10; j++)
-      {
-         MessageReference ref = generateReference(queue, i);
-
-         assertEquals(HandleStatus.BUSY, queue.addLast(ref));
-      }
-
-      assertEquals(maxSize, queue.getMaxSizeBytes());
-      assertEquals(size, queue.getSizeBytes());
-   }
-
    public void testWithPriorities()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       final int numMessages = 10;
 
@@ -946,7 +872,7 @@
 
    public void testConsumerWithFilterAddAndRemove()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       Filter filter = new FakeFilter("fruit", "orange");
 
@@ -955,7 +881,7 @@
 
    public void testList()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       final int numMessages = 20;
 
@@ -979,7 +905,7 @@
 
    public void testListWithFilter()
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       final int numMessages = 20;
 
@@ -1015,7 +941,7 @@
 
    public void testConsumeWithFiltersAddAndRemoveConsumer() throws Exception
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       Filter filter = new FakeFilter("fruit", "orange");
 
@@ -1088,7 +1014,7 @@
 
    private void testConsumerWithFilters(boolean direct) throws Exception
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
 
       Filter filter = new FakeFilter("fruit", "orange");
 
@@ -1177,7 +1103,7 @@
    public void testMessageOrder() throws Exception
    {
       Consumer consumer = EasyMock.createStrictMock(Consumer.class);
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       MessageReference messageReference = generateReference(queue, 1);
       MessageReference messageReference2 = generateReference(queue, 2);
       MessageReference messageReference3 = generateReference(queue, 3);
@@ -1195,7 +1121,7 @@
 
    public void testMessagesAdded() throws Exception
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       MessageReference messageReference = generateReference(queue, 1);
       MessageReference messageReference2 = generateReference(queue, 2);
       MessageReference messageReference3 = generateReference(queue, 3);
@@ -1208,7 +1134,7 @@
    public void testAddLastWhenLocked() throws Exception
    {
 
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       MessageReference messageReference = generateReference(queue, 1);
       queue.lock();
       CountDownLatch countDownLatch = new CountDownLatch(1);
@@ -1224,7 +1150,7 @@
    public void testAddLastWhenLockedMultiple() throws Exception
    {
 
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       MessageReference messageReference = generateReference(queue, 1);
       MessageReference messageReference2 = generateReference(queue, 2);
       MessageReference messageReference3 = generateReference(queue, 3);
@@ -1250,7 +1176,7 @@
    public void testAddFirstWhenLocked() throws Exception
    {
 
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       MessageReference messageReference = generateReference(queue, 1);
       queue.lock();
       CountDownLatch countDownLatch = new CountDownLatch(1);
@@ -1266,7 +1192,7 @@
    public void testAddFirstWhenLockedMultiple() throws Exception
    {
 
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       MessageReference messageReference = generateReference(queue, 1);
       MessageReference messageReference2 = generateReference(queue, 2);
       MessageReference messageReference3 = generateReference(queue, 3);
@@ -1292,7 +1218,7 @@
    public void testAddListFirst() throws Exception
    {
       Consumer consumer = EasyMock.createStrictMock(Consumer.class);
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       MessageReference messageReference = generateReference(queue, 1);
       MessageReference messageReference2 = generateReference(queue, 2);
       MessageReference messageReference3 = generateReference(queue, 3);
@@ -1313,7 +1239,7 @@
    public void testRemoveReferenceWithId() throws Exception
    {
       Consumer consumer = EasyMock.createStrictMock(Consumer.class);
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       MessageReference messageReference = generateReference(queue, 1);
       MessageReference messageReference2 = generateReference(queue, 2);
       MessageReference messageReference3 = generateReference(queue, 3);
@@ -1334,7 +1260,7 @@
 
    public void testGetReference() throws Exception
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       MessageReference messageReference = generateReference(queue, 1);
       MessageReference messageReference2 = generateReference(queue, 2);
       MessageReference messageReference3 = generateReference(queue, 3);
@@ -1347,7 +1273,7 @@
 
    public void testGetNonExistentReference() throws Exception
    {
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       MessageReference messageReference = generateReference(queue, 1);
       MessageReference messageReference2 = generateReference(queue, 2);
       MessageReference messageReference3 = generateReference(queue, 3);
@@ -1361,7 +1287,7 @@
    public void testConsumerRemovedAfterException() throws Exception
    {
       Consumer consumer = EasyMock.createStrictMock(Consumer.class);
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       MessageReference messageReference = generateReference(queue, 1);
       MessageReference messageReference2 = generateReference(queue, 2);
       MessageReference messageReference3 = generateReference(queue, 3);
@@ -1381,7 +1307,7 @@
    public void testDeliveryAsync() throws Exception
    {
       Consumer consumer = EasyMock.createStrictMock(Consumer.class);
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       MessageReference messageReference = generateReference(queue, 1);
       MessageReference messageReference2 = generateReference(queue, 2);
       MessageReference messageReference3 = generateReference(queue, 3);
@@ -1410,14 +1336,24 @@
    {
       long messageID = randomLong();
       final SimpleString expiryQueue = new SimpleString("expiryQueue");
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       MessageReference messageReference = generateReference(queue, messageID);
       StorageManager storageManager = EasyMock.createMock(StorageManager.class);
       EasyMock.expect(storageManager.generateTransactionID()).andReturn(randomLong());
       EasyMock.expect(storageManager.generateMessageID()).andReturn(randomLong());
       storageManager.storeDeleteTransactional(EasyMock.anyLong(), EasyMock.eq(messageID));
       storageManager.commit(EasyMock.anyLong());
-      PostOffice postOffice = createMock(PostOffice.class);      
+
+      PostOffice postOffice = createMock(PostOffice.class);
+      PagingManager pm = EasyMock.createNiceMock(PagingManager.class);
+      EasyMock.expect(pm.page(EasyMock.isA(ServerMessage.class))).andStubReturn(false);
+      EasyMock.expect(postOffice.getPagingManager()).andStubReturn(pm);
+      EasyMock.expect(pm.isPaging(EasyMock.isA(SimpleString.class))).andStubReturn(false);
+      pm.messageDone(EasyMock.isA(ServerMessage.class));
+      EasyMock.expectLastCall().anyTimes();
+      
+      
+      
       Binding expiryBinding = createMock(Binding.class);
       EasyMock.expect(expiryBinding.getAddress()).andStubReturn(expiryQueue);
       EasyMock.expect(postOffice.getBinding(expiryQueue)).andReturn(expiryBinding );
@@ -1433,7 +1369,7 @@
       };
       EasyMock.expect(queueSettingsRepository.getMatch(queue1.toString())).andStubReturn(queueSettings);
 
-      EasyMock.replay(storageManager, postOffice, queueSettingsRepository, expiryBinding);
+      EasyMock.replay(storageManager, postOffice, queueSettingsRepository, expiryBinding, pm);
 
       assertEquals(0, queue.getMessageCount());
       assertEquals(0, queue.getDeliveringCount());
@@ -1451,21 +1387,30 @@
       assertEquals(0, queue.getDeliveringCount());
       assertEquals(0, queue.getSizeBytes());
 
-      EasyMock.verify(storageManager, postOffice, queueSettingsRepository, expiryBinding);
+      EasyMock.verify(storageManager, postOffice, queueSettingsRepository, expiryBinding, pm);
    }
 
    public void testSendMessageToDLQ() throws Exception
    {
       long messageID = randomLong();
       final SimpleString dlqName = new SimpleString("dlq");
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       MessageReference messageReference = generateReference(queue, messageID);
       StorageManager storageManager = createMock(StorageManager.class);
       expect(storageManager.generateTransactionID()).andReturn(randomLong());
       expect(storageManager.generateMessageID()).andReturn(randomLong());
       storageManager.storeDeleteTransactional(anyLong(), eq(messageID));
       storageManager.commit(anyLong());
-      PostOffice postOffice = createMock(PostOffice.class);      
+      
+      PostOffice postOffice = createMock(PostOffice.class);
+      PagingManager pm = EasyMock.createNiceMock(PagingManager.class);
+      EasyMock.expect(pm.page(EasyMock.isA(ServerMessage.class))).andStubReturn(false);
+      EasyMock.expect(postOffice.getPagingManager()).andStubReturn(pm);
+      EasyMock.expect(pm.isPaging(EasyMock.isA(SimpleString.class))).andStubReturn(false);
+      pm.messageDone(EasyMock.isA(ServerMessage.class));
+      EasyMock.expectLastCall().anyTimes();
+      
+      
       Binding dlqBinding = createMock(Binding.class);
       expect(dlqBinding.getAddress()).andStubReturn(dlqName);
       expect(postOffice.getBinding(dlqName)).andReturn(dlqBinding );
@@ -1481,7 +1426,7 @@
       };
       EasyMock.expect(queueSettingsRepository.getMatch(queue1.toString())).andStubReturn(queueSettings);
 
-      EasyMock.replay(storageManager, postOffice, queueSettingsRepository, dlqBinding);
+      EasyMock.replay(storageManager, postOffice, queueSettingsRepository, dlqBinding, pm);
 
       assertEquals(0, queue.getMessageCount());
       assertEquals(0, queue.getDeliveringCount());
@@ -1499,7 +1444,7 @@
       assertEquals(0, queue.getDeliveringCount());
       assertEquals(0, queue.getSizeBytes());
 
-      EasyMock.verify(storageManager, postOffice, queueSettingsRepository, dlqBinding);
+      EasyMock.verify(storageManager, postOffice, queueSettingsRepository, dlqBinding, pm);
    }
    
    public void testMoveMessage() throws Exception
@@ -1508,7 +1453,7 @@
       long newMessageID = randomLong();
       long tid = randomLong();
       final SimpleString toQueueName = new SimpleString("toQueueName");
-      Queue queue = new QueueImpl(1, queue1, null, false, true, -1, scheduledExecutor);
+      Queue queue = new QueueImpl(1, queue1, null, false, true, new QueueSettings(), scheduledExecutor);
       Queue toQueue = createMock(Queue.class);
     
       MessageReference messageReference = generateReference(queue, messageID);
@@ -1517,14 +1462,24 @@
       EasyMock.expect(storageManager.generateTransactionID()).andReturn(tid);
       storageManager.storeDeleteTransactional(EasyMock.anyLong(), EasyMock.eq(messageID));
       storageManager.commit(EasyMock.anyLong());
+      
       PostOffice postOffice = EasyMock.createMock(PostOffice.class);      
+
+      PagingManager pm = EasyMock.createNiceMock(PagingManager.class);
+      EasyMock.expect(pm.page(EasyMock.isA(ServerMessage.class))).andStubReturn(false);
+      EasyMock.expect(postOffice.getPagingManager()).andStubReturn(pm);
+      EasyMock.expect(pm.isPaging(EasyMock.isA(SimpleString.class))).andStubReturn(false);
+      pm.messageDone(EasyMock.isA(ServerMessage.class));
+      EasyMock.expectLastCall().anyTimes();
+
+      
       Binding toBinding = EasyMock.createMock(Binding.class);
       EasyMock.expect(toBinding.getAddress()).andStubReturn(toQueueName);
       EasyMock.expect(toBinding.getQueue()).andStubReturn(toQueue);
       EasyMock.expect(postOffice.route(EasyMock.isA(ServerMessage.class))).andReturn(new ArrayList<MessageReference>());
       HierarchicalRepository<QueueSettings> queueSettingsRepository = EasyMock.createMock(HierarchicalRepository.class);
 
-      EasyMock.replay(storageManager, postOffice, queueSettingsRepository, toBinding);
+      EasyMock.replay(storageManager, postOffice, queueSettingsRepository, toBinding, pm);
 
       assertEquals(0, queue.getMessageCount());
       assertEquals(0, queue.getDeliveringCount());
@@ -1542,7 +1497,7 @@
       assertEquals(0, queue.getDeliveringCount());
       assertEquals(0, queue.getSizeBytes());
 
-      EasyMock.verify(storageManager, postOffice, queueSettingsRepository, toBinding);
+      EasyMock.verify(storageManager, postOffice, queueSettingsRepository, toBinding, pm);
    }
    
    // Inner classes ---------------------------------------------------------------

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/ServerConsumerImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/ServerConsumerImplTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/ServerConsumerImplTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -198,6 +198,7 @@
    {
       MessageReference messageReference = createStrictMock(MessageReference.class);
       ServerMessage message = createStrictMock(ServerMessage.class);
+      expect(message.decrementRefCount()).andStubReturn(1);
       expect(messageReference.getMessage()).andStubReturn(message);
       MessageReference messageReference2 = createStrictMock(MessageReference.class);
       ServerMessage message2 = createStrictMock(ServerMessage.class);

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/ServerMessageImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/ServerMessageImplTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/ServerMessageImplTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -134,10 +134,10 @@
       
       assertEquals(2, msg.getDurableRefCount());
       
-      msg.incrementDurableRefCount();
+      msg.incrementReference(true);
       assertEquals(3, msg.getDurableRefCount());
       
-      msg.incrementDurableRefCount();
+      msg.incrementReference(true);
       assertEquals(4, msg.getDurableRefCount());
       
       msg.decrementDurableRefCount();

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/ServerSessionImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/ServerSessionImplTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/ServerSessionImplTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -47,6 +47,7 @@
 import org.easymock.IAnswer;
 import org.jboss.messaging.core.exception.MessagingException;
 import org.jboss.messaging.core.filter.Filter;
+import org.jboss.messaging.core.paging.PagingManager;
 import org.jboss.messaging.core.persistence.StorageManager;
 import org.jboss.messaging.core.postoffice.Binding;
 import org.jboss.messaging.core.postoffice.FlowController;
@@ -93,12 +94,14 @@
 
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @author <a href="mailto:ataylor at redhat.com">Andy Taylor</a>
+* @author <a href="mailto:ataylor at redhat.com">Clebert Suconic</a>
  */
 public class ServerSessionImplTest extends UnitTestCase
 {
    private RemotingConnection rc;
    private StorageManager sm;
    private PostOffice po;
+   private PagingManager pm;   
    private HierarchicalRepository<QueueSettings> qs;
    private ResourceManager rm;
    private SecurityStore ss;
@@ -132,6 +135,10 @@
       RemotingConnection returner = createStrictMock(RemotingConnection.class);
       StorageManager sm = createStrictMock(StorageManager.class);
       PostOffice po = createStrictMock(PostOffice.class);
+
+      PagingManager pm = createNiceMock(PagingManager.class);
+      expect(po.getPagingManager()).andStubReturn(pm);
+      
       HierarchicalRepository<QueueSettings> qs = createStrictMock(HierarchicalRepository.class);
       ResourceManager rm = createStrictMock(ResourceManager.class);
       SecurityStore ss = createStrictMock(SecurityStore.class);
@@ -150,7 +157,7 @@
       
       expectLastCall().andThrow(new MessagingException(MessagingException.SECURITY_EXCEPTION));
 
-      replay(returner, sm, po, qs, rm, ss, pd, executor, msg, server, cm);
+      replay(returner, sm, po, qs, rm, ss, pd, executor, msg, server, cm, pm);
 
       ServerSessionImpl session = new ServerSessionImpl(123, "blah", null, null, true, false, false,
               returner, server, sm, po, qs, rm, ss, pd, executor, cm);
@@ -165,7 +172,7 @@
          //Ok
       }
 
-      verify(returner, sm, po, qs, rm, ss, pd, executor, msg, server, cm);
+      verify(returner, sm, po, qs, rm, ss, pd, executor, msg, server, cm, pm);
    }
 
    public void testNotAutoCommitSendFailsSecurity() throws Exception
@@ -173,6 +180,10 @@
       RemotingConnection returner = createStrictMock(RemotingConnection.class);
       StorageManager sm = createStrictMock(StorageManager.class);
       PostOffice po = createStrictMock(PostOffice.class);
+
+      PagingManager pm = createNiceMock(PagingManager.class);
+      expect(po.getPagingManager()).andStubReturn(pm);
+      
       HierarchicalRepository<QueueSettings> qs = createStrictMock(HierarchicalRepository.class);
       ResourceManager rm = createStrictMock(ResourceManager.class);
       SecurityStore ss = createStrictMock(SecurityStore.class);
@@ -190,7 +201,7 @@
       expectLastCall().andThrow(new MessagingException(MessagingException.SECURITY_EXCEPTION));
 
 
-      replay(returner, sm, po, qs, rm, ss, pd, executor, msg, server, cm);
+      replay(returner, sm, po, qs, rm, ss, pd, executor, msg, server, cm, pm);
 
       ServerSessionImpl session = new ServerSessionImpl(123, "blah", null, null, false, false, false,
                returner, server, sm, po, qs, rm, ss, pd, executor, cm);
@@ -205,7 +216,7 @@
          //Ok
       }
 
-      verify(returner, sm, po, qs, rm, ss, pd, executor, msg, server, cm);
+      verify(returner, sm, po, qs, rm, ss, pd, executor, msg, server, cm, pm);
 
       assertEquals(Transaction.State.ROLLBACK_ONLY, session.getTransaction().getState());
    }
@@ -546,6 +557,8 @@
 
    public void testRollback() throws Exception
    {
+      ServerSessionImpl session = create(false);
+
       ServerConsumer consumer = createStrictMock(ServerConsumer.class);
       expect(consumer.getClientTargetID()).andStubReturn(999l);
       MessageReference[] references = new MessageReference[10];
@@ -556,6 +569,8 @@
       {
          references[i] = createStrictMock(MessageReference.class);
          messages[i] = createStrictMock(ServerMessage.class);
+         expect(messages[i].decrementRefCount()).andReturn(0);
+         pm.messageDone(messages[i]);
          expect(messages[i].isDurable()).andStubReturn(false);
          expect(references[i].getMessage()).andStubReturn(messages[i]);
          expect(references[i].getDeliveryCount()).andReturn(0);
@@ -563,7 +578,6 @@
       }
       QueueSettings queueSettings = new QueueSettings();
       SimpleString address = new SimpleString("qName");
-      ServerSessionImpl session = create(false);
       Binding binding = createStrictMock(Binding.class);
       expect(po.getBinding(address)).andStubReturn(binding);
       expect(binding.getAddress()).andStubReturn(address);
@@ -582,13 +596,15 @@
       queue.lock();
       for (int i = 0; i < 10; i++)
       {
+         expect(messages[i].incrementReference(false)).andReturn(1);
+         expect(pm.addSize(messages[i])).andReturn(1l);
          expect(references[i].cancel(sm, po, qs)).andReturn(true);
       }
       queue.addListFirst((LinkedList<MessageReference>) anyObject());
       queue.unlock();
 
       expect(sm.generateTransactionID()).andReturn(65l);
-      replay(rc, sm, po, qs, rm, ss, pd, cm, server, executor, binding, queue, consumer);
+      replay(rc, sm, po, qs, rm, ss, pd, cm, server, executor, binding, queue, consumer, pm);
       replay((Object[]) references);
       replay((Object[]) messages);
       //we need to create a consumer to verify things get rolled back
@@ -598,13 +614,15 @@
          session.handleDelivery(reference, consumer);
       }
       session.rollback();
-      verify(rc, sm, po, qs, rm, ss, pd, cm, server, executor, binding, queue, consumer);
+      verify(rc, sm, po, qs, rm, ss, pd, cm, server, executor, binding, queue, consumer, pm);
       verify((Object[]) references);
       verify((Object[]) messages);
    }
 
    public void testCancelAll() throws Exception
    {
+      ServerSessionImpl session = create(false);
+
       ServerConsumer consumer = createStrictMock(ServerConsumer.class);
       expect(consumer.getClientTargetID()).andStubReturn(999l);
       MessageReference[] references = new MessageReference[10];
@@ -615,6 +633,10 @@
       {
          references[i] = createStrictMock(MessageReference.class);
          messages[i] = createStrictMock(ServerMessage.class);
+         
+         expect(messages[i].decrementRefCount()).andReturn(0);
+         pm.messageDone(messages[i]);
+         
          expect(messages[i].isDurable()).andStubReturn(false);
          expect(references[i].getMessage()).andStubReturn(messages[i]);
          expect(references[i].getDeliveryCount()).andReturn(0);
@@ -622,7 +644,6 @@
       }
       QueueSettings queueSettings = new QueueSettings();
       SimpleString address = new SimpleString("qName");
-      ServerSessionImpl session = create(false);
       Binding binding = createStrictMock(Binding.class);
       expect(po.getBinding(address)).andStubReturn(binding);
       expect(binding.getAddress()).andStubReturn(address);
@@ -642,13 +663,15 @@
       queue.lock();
       for (int i = 0; i < 10; i++)
       {
+         expect(messages[i].incrementReference(false)).andReturn(1);
+         expect(pm.addSize(messages[i])).andReturn(1l);
          expect(references[i].cancel(sm, po, qs)).andReturn(true);
       }
       queue.addListFirst((LinkedList<MessageReference>) anyObject());
       queue.unlock();
 
       expect(sm.generateTransactionID()).andReturn(65l);
-      replay(rc, sm, po, qs, rm, ss, pd, cm, server, executor, binding, queue, consumer);
+      replay(rc, sm, po, qs, rm, ss, pd, cm, server, executor, binding, queue, consumer, pm);
       replay((Object[]) references);
       replay((Object[]) messages);
       //we need to create a consumer to verify things get rolled back
@@ -658,7 +681,7 @@
          session.handleDelivery(reference, consumer);
       }
       session.cancel(-1, false);
-      verify(rc, sm, po, qs, rm, ss, pd, cm, server, executor, binding, queue, consumer);
+      verify(rc, sm, po, qs, rm, ss, pd, cm, server, executor, binding, queue, consumer, pm);
       verify((Object[]) references);
       verify((Object[]) messages);
    }
@@ -717,6 +740,8 @@
 
    public void testCommit() throws Exception
    {
+      ServerSessionImpl session = create(false);
+
       ServerConsumer consumer = createStrictMock(ServerConsumer.class);
       expect(consumer.getClientTargetID()).andStubReturn(999l);
       MessageReference[] references = new MessageReference[10];
@@ -727,6 +752,10 @@
       {
          references[i] = createStrictMock(MessageReference.class);
          messages[i] = createStrictMock(ServerMessage.class);
+         
+         expect(messages[i].decrementRefCount()).andReturn(0);
+         pm.messageDone(messages[i]);
+         
          expect(messages[i].isDurable()).andStubReturn(false);
          expect(references[i].getMessage()).andStubReturn(messages[i]);
          expect(references[i].getDeliveryCount()).andReturn(0);
@@ -735,7 +764,6 @@
       }
       QueueSettings queueSettings = new QueueSettings();
       SimpleString address = new SimpleString("qName");
-      ServerSessionImpl session = create(false);
       Binding binding = createStrictMock(Binding.class);
       expect(po.getBinding(address)).andStubReturn(binding);
       expect(binding.getAddress()).andStubReturn(address);
@@ -754,7 +782,7 @@
       }
       expect(sm.generateTransactionID()).andReturn(10l);
 
-      replay(rc, sm, po, qs, rm, ss, pd, cm, server, executor, binding, queue, consumer);
+      replay(rc, sm, po, qs, rm, ss, pd, cm, server, executor, binding, queue, consumer, pm);
       replay((Object[]) references);
       replay((Object[]) messages);
       session.createConsumer(1, address, null, -1, 99);
@@ -764,7 +792,7 @@
       }
       session.acknowledge(10, true);
       session.commit();
-      verify(rc, sm, po, qs, rm, ss, pd, cm, server, executor, binding, queue, consumer);
+      verify(rc, sm, po, qs, rm, ss, pd, cm, server, executor, binding, queue, consumer, pm);
       verify((Object[]) references);
       verify((Object[]) messages);
    }
@@ -1486,12 +1514,17 @@
       ServerSessionImpl session = create(false);
       SimpleString address = new SimpleString("testQ");
       Binding binding = createStrictMock(Binding.class);
-      Queue queue = createStrictMock(Queue.class);
+      Queue queue = createMock(Queue.class);
+      
+      QueueSettings settings = new QueueSettings();
+      settings.setMaxSizeBytes(12345);
+      expect(queue.getSettings()).andReturn(settings);
+      
       expect(po.getBinding(address)).andReturn(binding);
+      
       expect(binding.getQueue()).andReturn(queue);
       expect(queue.getFilter()).andReturn(null);
       expect(queue.isDurable()).andReturn(true);     
-      expect(queue.getMaxSizeBytes()).andReturn(12345);
       expect(queue.getConsumerCount()).andReturn(2);
       expect(queue.getMessageCount()).andReturn(6789);
       expect(binding.getAddress()).andReturn(address);
@@ -1513,7 +1546,14 @@
       ServerSessionImpl session = create(false);
       SimpleString address = new SimpleString("testQ");
       Binding binding = createStrictMock(Binding.class);
-      Queue queue = createStrictMock(Queue.class);
+      Queue queue = createMock(Queue.class);
+
+      
+      QueueSettings settings = new QueueSettings();
+      settings.setMaxSizeBytes(12345);
+      expect(queue.getSettings()).andReturn(settings);
+
+      
       Filter filter = createStrictMock(Filter.class);
       expect(po.getBinding(address)).andReturn(binding);
       expect(binding.getQueue()).andReturn(queue);
@@ -1521,7 +1561,6 @@
       SimpleString filterString = new SimpleString("myprop = 'ddddd'");
       expect(filter.getFilterString()).andReturn(filterString);
       expect(queue.isDurable()).andReturn(true);      
-      expect(queue.getMaxSizeBytes()).andReturn(12345);
       expect(queue.getConsumerCount()).andReturn(2);
       expect(queue.getMessageCount()).andReturn(6789);
       expect(binding.getAddress()).andReturn(address);
@@ -1641,6 +1680,9 @@
       rc = createStrictMock(RemotingConnection.class);
       sm = createStrictMock(StorageManager.class);
       po = createStrictMock(PostOffice.class);
+      pm = createNiceMock(PagingManager.class);
+      expect(po.getPagingManager()).andStubReturn(pm);
+      
       qs = createStrictMock(HierarchicalRepository.class);
       rm = createStrictMock(ResourceManager.class);
       ss = createStrictMock(SecurityStore.class);
@@ -1652,11 +1694,12 @@
       {
          expect(sm.generateTransactionID()).andReturn(999l);
       }
-      replay(rc, sm, po, qs, rm, ss, pd, cm, server, executor);
+      replay(rc, sm, po, qs, rm, ss, pd, cm, server, executor, pm);
       ServerSessionImpl sess = new ServerSessionImpl(123, "blah", null, null, false, false, xa,
               rc, server, sm, po, qs, rm, ss, pd, executor, cm);
-      verify(rc, sm, po, qs, rm, ss, pd, cm, server, executor);
-      reset(rc, sm, po, qs, rm, ss, pd, cm, server, executor);
+      verify(rc, sm, po, qs, rm, ss, pd, cm, server, executor, pm);
+      reset(rc, sm, po, qs, rm, ss, pd, cm, server, executor, pm);
+      expect(po.getPagingManager()).andStubReturn(pm);
       return sess;
    }
 
@@ -1667,6 +1710,10 @@
       RemotingConnection returner = createStrictMock(RemotingConnection.class);
       StorageManager sm = createStrictMock(StorageManager.class);
       PostOffice po = createStrictMock(PostOffice.class);
+
+      PagingManager pm = createNiceMock(PagingManager.class);
+      expect(po.getPagingManager()).andStubReturn(pm);
+      
       HierarchicalRepository<QueueSettings> qs = createStrictMock(HierarchicalRepository.class);
       ResourceManager rm = createStrictMock(ResourceManager.class);
       SecurityStore ss = createStrictMock(SecurityStore.class);
@@ -1693,7 +1740,7 @@
          refs.add(ref);
       }
 
-      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, cm, server);
+      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, cm, server, pm);
       replay(refs.toArray());
 
       ServerSessionImpl session = new ServerSessionImpl(123, "blah", null, null, false, false, false,
@@ -1717,7 +1764,7 @@
 
       //Now ack half of them
 
-      reset(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm);
+      reset(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm, pm);
       reset(refs.toArray());
 
       Queue queue = createMock(Queue.class);
@@ -1727,6 +1774,8 @@
          ServerMessage msg = createMock(ServerMessage.class);
 
          expect(ref.getMessage()).andStubReturn(msg);
+         expect(msg.decrementRefCount()).andReturn(0);
+         pm.messageDone(msg);
          expect(ref.getQueue()).andStubReturn(queue);
          expect(msg.isDurable()).andStubReturn(durableMsg);
          if (durableMsg)
@@ -1749,7 +1798,7 @@
          }
       }
 
-      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm);
+      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm, pm);
       replay(refs.toArray());
 
       session.acknowledge(numRefs / 2 - 1, true);
@@ -1767,7 +1816,7 @@
 
       //Now ack the rest
 
-      reset(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm);
+      reset(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm, pm);
       reset(refs.toArray());
 
       for (i = numRefs / 2; i < numRefs; i++)
@@ -1775,6 +1824,9 @@
          MessageReference ref = refs.get(i);
          ServerMessage msg = createMock(ServerMessage.class);
 
+         expect(msg.decrementRefCount()).andReturn(0);
+         pm.messageDone(msg);
+         
          expect(ref.getMessage()).andStubReturn(msg);
          expect(ref.getQueue()).andStubReturn(queue);
          expect(msg.isDurable()).andStubReturn(true);
@@ -1792,12 +1844,12 @@
          }
       }
 
-      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm);
+      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm, pm);
       replay(refs.toArray());
 
       session.acknowledge(numRefs - 1, true);
 
-      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue);
+      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, pm);
       verify(refs.toArray());
 
       assertEquals(0, session.getDeliveries().size());
@@ -1809,6 +1861,10 @@
       RemotingConnection returner = createStrictMock(RemotingConnection.class);
       StorageManager sm = createStrictMock(StorageManager.class);
       PostOffice po = createStrictMock(PostOffice.class);
+
+      PagingManager pm = createNiceMock(PagingManager.class);
+      expect(po.getPagingManager()).andStubReturn(pm);
+      
       HierarchicalRepository<QueueSettings> qs = createStrictMock(HierarchicalRepository.class);
       ResourceManager rm = createStrictMock(ResourceManager.class);
       SecurityStore ss = createStrictMock(SecurityStore.class);
@@ -1835,7 +1891,7 @@
          refs.add(ref);
       }
 
-      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm);
+      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm, pm);
       replay(refs.toArray());
 
       ServerSessionImpl session = new ServerSessionImpl(123, "blah", null, null, false, false, false,
@@ -1846,7 +1902,7 @@
          session.handleDelivery(ref, consumer);
       }
 
-      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm);
+      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm, pm);
       verify(refs.toArray());
 
       assertEquals(numRefs, session.getDeliveries().size());
@@ -1859,7 +1915,7 @@
 
       //Now ack half of them
 
-      reset(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm);
+      reset(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm, pm);
       reset(refs.toArray());
 
       Queue queue = createMock(Queue.class);
@@ -1868,6 +1924,9 @@
          MessageReference ref = refs.get(i);
          ServerMessage msg = createMock(ServerMessage.class);
 
+         expect(msg.decrementRefCount()).andReturn(0);
+         pm.messageDone(msg);
+         
          expect(ref.getMessage()).andStubReturn(msg);
          expect(ref.getQueue()).andStubReturn(queue);
          expect(msg.isDurable()).andStubReturn(durableMsg);
@@ -1891,7 +1950,7 @@
          }
       }
 
-      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm);
+      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm, pm);
       replay(refs.toArray());
       for (i = 0; i < numRefs / 2; i++)
       {
@@ -1899,7 +1958,7 @@
       }
 
 
-      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm);
+      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm, pm);
       verify(refs.toArray());
 
       assertEquals(numRefs / 2, session.getDeliveries().size());
@@ -1912,7 +1971,7 @@
 
       //Now ack the rest
 
-      reset(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm);
+      reset(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm, pm);
       reset(refs.toArray());
 
       for (i = numRefs / 2; i < numRefs; i++)
@@ -1920,6 +1979,9 @@
          MessageReference ref = refs.get(i);
          ServerMessage msg = createMock(ServerMessage.class);
 
+         expect(msg.decrementRefCount()).andReturn(0);
+         pm.messageDone(msg);
+         
          expect(ref.getMessage()).andStubReturn(msg);
          expect(ref.getQueue()).andStubReturn(queue);
          expect(msg.isDurable()).andStubReturn(true);
@@ -1937,7 +1999,7 @@
          }
       }
 
-      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm);
+      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm, pm);
       replay(refs.toArray());
 
       for (i = numRefs / 2; i < numRefs; i++)
@@ -1945,7 +2007,7 @@
          session.acknowledge(i, false);
       }
 
-      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm);
+      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm, pm);
       verify(refs.toArray());
 
       assertEquals(0, session.getDeliveries().size());
@@ -1957,6 +2019,10 @@
       RemotingConnection returner = createStrictMock(RemotingConnection.class);
       StorageManager sm = createStrictMock(StorageManager.class);
       PostOffice po = createStrictMock(PostOffice.class);
+
+      PagingManager pm = createNiceMock(PagingManager.class);
+      expect(po.getPagingManager()).andStubReturn(pm);
+      
       HierarchicalRepository<QueueSettings> qs = createStrictMock(HierarchicalRepository.class);
       ResourceManager rm = createStrictMock(ResourceManager.class);
       SecurityStore ss = createStrictMock(SecurityStore.class);
@@ -1973,7 +2039,7 @@
       List<MessageReference> refs = new ArrayList<MessageReference>();
       for (int i = 0; i < numRefs; i++)
       {
-         MessageReference ref = createStrictMock(MessageReference.class);
+         MessageReference ref = createNiceMock(MessageReference.class);
 
          expect(consumer.getClientTargetID()).andReturn(76767L);
          expect(ref.getMessage()).andReturn(createMock(ServerMessage.class));
@@ -1982,7 +2048,7 @@
          refs.add(ref);
       }
 
-      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm);
+      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm, pm);
       replay(refs.toArray());
 
       ServerSessionImpl session = new ServerSessionImpl(123, "bah", null, null, false, true, false,
@@ -1993,7 +2059,7 @@
          session.handleDelivery(ref, consumer);
       }
 
-      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm);
+      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm, pm);
       verify(refs.toArray());
 
       assertEquals(numRefs, session.getDeliveries().size());
@@ -2006,19 +2072,21 @@
 
       //Now ack half of them
 
-      reset(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm);
+      reset(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm, pm);
       reset(refs.toArray());
 
       Queue queue = createMock(Queue.class);
       for (i = 0; i < numRefs / 2; i++)
       {
          MessageReference ref = refs.get(i);
-         ServerMessage msg = createMock(ServerMessage.class);
+         ServerMessage msg = createNiceMock(ServerMessage.class);
 
          expect(ref.getMessage()).andStubReturn(msg);
          expect(ref.getQueue()).andStubReturn(queue);
          expect(msg.isDurable()).andStubReturn(durableMsg);
          expect(queue.isDurable()).andStubReturn(durableQueue);
+         expect(msg.decrementRefCount()).andReturn(0);
+         pm.messageDone(msg);
          if (durableMsg && durableQueue)
          {
             expect(msg.decrementDurableRefCount()).andStubReturn(numRefs);
@@ -2035,12 +2103,12 @@
          }
       }
 
-      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm);
+      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm, pm);
       replay(refs.toArray());
 
       session.acknowledge(numRefs / 2 - 1, true);
 
-      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm);
+      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm, pm);
       verify(refs.toArray());
 
       assertEquals(numRefs / 2, session.getDeliveries().size());
@@ -2053,7 +2121,7 @@
 
       //Now ack the rest
 
-      reset(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm);
+      reset(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm, pm);
       reset(refs.toArray());
 
       for (i = numRefs / 2; i < numRefs; i++)
@@ -2064,6 +2132,8 @@
          expect(ref.getMessage()).andStubReturn(msg);
          expect(ref.getQueue()).andStubReturn(queue);
          expect(msg.isDurable()).andStubReturn(true);
+         expect(msg.decrementRefCount()).andReturn(0);
+         pm.messageDone(msg);
          expect(queue.isDurable()).andStubReturn(true);
          expect(msg.decrementDurableRefCount()).andStubReturn(numRefs);
          final long queueID = 1929012;
@@ -2078,12 +2148,12 @@
          }
       }
 
-      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm);
+      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm, pm);
       replay(refs.toArray());
 
       session.acknowledge(numRefs - 1, true);
 
-      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm);
+      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm, pm);
       verify(refs.toArray());
 
       assertEquals(0, session.getDeliveries().size());
@@ -2095,6 +2165,10 @@
       RemotingConnection returner = createStrictMock(RemotingConnection.class);
       StorageManager sm = createStrictMock(StorageManager.class);
       PostOffice po = createStrictMock(PostOffice.class);
+
+      PagingManager pm = createNiceMock(PagingManager.class);
+      expect(po.getPagingManager()).andStubReturn(pm);
+      
       HierarchicalRepository<QueueSettings> qs = createStrictMock(HierarchicalRepository.class);
       ResourceManager rm = createStrictMock(ResourceManager.class);
       SecurityStore ss = createStrictMock(SecurityStore.class);
@@ -2120,7 +2194,7 @@
          refs.add(ref);
       }
 
-      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm);
+      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm, pm);
       replay(refs.toArray());
 
       ServerSessionImpl session = new ServerSessionImpl(123, "blah", null, null, false, true, false,
@@ -2131,7 +2205,7 @@
          session.handleDelivery(ref, consumer);
       }
 
-      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm);
+      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm, pm);
       verify(refs.toArray());
 
       assertEquals(numRefs, session.getDeliveries().size());
@@ -2144,7 +2218,7 @@
 
       //Now ack half of them
 
-      reset(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm);
+      reset(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, server, cm, pm);
       reset(refs.toArray());
 
       Queue queue = createMock(Queue.class);
@@ -2153,6 +2227,9 @@
          MessageReference ref = refs.get(i);
          ServerMessage msg = createMock(ServerMessage.class);
 
+         expect(msg.decrementRefCount()).andReturn(0);
+         pm.messageDone(msg);
+         
          expect(ref.getMessage()).andStubReturn(msg);
          expect(ref.getQueue()).andStubReturn(queue);
          expect(msg.isDurable()).andStubReturn(durableMsg);
@@ -2173,7 +2250,7 @@
          }
       }
 
-      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm);
+      replay(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm, pm);
       replay(refs.toArray());
 
       for (i = 0; i < numRefs / 2; i++)
@@ -2181,7 +2258,7 @@
          session.acknowledge(i, false);
       }
 
-      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm);
+      verify(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm, pm);
       verify(refs.toArray());
 
       assertEquals(numRefs / 2, session.getDeliveries().size());
@@ -2194,7 +2271,7 @@
 
       //Now ack the rest
 
-      reset(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm);
+      reset(conn, returner, sm, po, qs, rm, ss, pd, executor, consumer, queue, server, cm, pm);
       reset(refs.toArray());
 
       for (i = numRefs / 2; i < numRefs; i++)
@@ -2202,6 +2279,9 @@
          MessageReference ref = refs.get(i);
          ServerMessage msg = createMock(ServerMessage.class);
 
+         expect(msg.decrementRefCount()).andReturn(0);
+         pm.messageDone(msg);
+         
          expect(ref.getMessage()).andStubReturn(msg);
          expect(ref.getQueue()).andStubReturn(queue);
          expect(msg.isDurable()).andStubReturn(true);
@@ -2238,6 +2318,10 @@
       RemotingConnection returner = createStrictMock(RemotingConnection.class);
       StorageManager sm = createStrictMock(StorageManager.class);
       PostOffice po = createStrictMock(PostOffice.class);
+
+      PagingManager pm = createNiceMock(PagingManager.class);
+      expect(po.getPagingManager()).andStubReturn(pm);
+      
       HierarchicalRepository<QueueSettings> qs = createStrictMock(HierarchicalRepository.class);
       ResourceManager rm = createStrictMock(ResourceManager.class);
       SecurityStore ss = createStrictMock(SecurityStore.class);
@@ -2281,14 +2365,14 @@
       expect(queue2.addLast(ref2)).andReturn(HandleStatus.HANDLED);
       expect(queue3.addLast(ref3)).andReturn(HandleStatus.HANDLED);
 
-      replay(returner, sm, po, qs, rm, ss, pd, executor, msg, ref1, ref2, ref3, queue1, queue2, queue3, server, cm);
+      replay(returner, sm, po, qs, rm, ss, pd, executor, msg, ref1, ref2, ref3, queue1, queue2, queue3, server, cm, pm);
 
       ServerSessionImpl session = new ServerSessionImpl(123, "blah", null, null, true, false, false,
               returner, server, sm, po, qs, rm, ss, pd, executor, cm);
 
       session.send(msg);
 
-      verify(returner, sm, po, qs, rm, ss, pd, executor, msg, ref1, ref2, ref3, queue1, queue2, queue3, server, cm);
+      verify(returner, sm, po, qs, rm, ss, pd, executor, msg, ref1, ref2, ref3, queue1, queue2, queue3, server, cm, pm);
    }
 
    private void testNotAutoCommitSend(final boolean persistent) throws Exception
@@ -2296,12 +2380,16 @@
       RemotingConnection returner = createStrictMock(RemotingConnection.class);
       StorageManager sm = createStrictMock(StorageManager.class);
       PostOffice po = createStrictMock(PostOffice.class);
+
+      PagingManager pm = createNiceMock(PagingManager.class);
+      expect(po.getPagingManager()).andStubReturn(pm);
+      
       HierarchicalRepository<QueueSettings> qs = createStrictMock(HierarchicalRepository.class);
       ResourceManager rm = createStrictMock(ResourceManager.class);
       SecurityStore ss = createStrictMock(SecurityStore.class);
       PacketDispatcher pd = createStrictMock(PacketDispatcher.class);
       Executor executor = createStrictMock(Executor.class);
-      ServerMessage msg = createStrictMock(ServerMessage.class);
+      ServerMessage msg = createNiceMock(ServerMessage.class);
       MessageReference ref1 = createStrictMock(MessageReference.class);
       MessageReference ref2 = createStrictMock(MessageReference.class);
       MessageReference ref3 = createStrictMock(MessageReference.class);
@@ -2330,14 +2418,14 @@
          sm.storeMessageTransactional(transactionID, msg);
       }
 
-      replay(returner, sm, po, qs, rm, ss, pd, executor, msg, ref1, ref2, ref3, server, cm);
+      replay(returner, sm, po, qs, rm, ss, pd, executor, msg, ref1, ref2, ref3, server, cm, pm);
 
       ServerSessionImpl session = new ServerSessionImpl(123, "blah", null, null, false, false, false,
               returner, server, sm, po, qs, rm, ss, pd, executor, cm);
 
       session.send(msg);
 
-      verify(returner, sm, po, qs, rm, ss, pd, executor, msg, ref1, ref2, ref3, server, cm);
+      verify(returner, sm, po, qs, rm, ss, pd, executor, msg, ref1, ref2, ref3, server, cm, pm);
    }
 
 
@@ -2346,6 +2434,10 @@
       RemotingConnection returner = createStrictMock(RemotingConnection.class);
       StorageManager sm = createStrictMock(StorageManager.class);
       PostOffice po = createStrictMock(PostOffice.class);
+
+      PagingManager pm = createNiceMock(PagingManager.class);
+      expect(po.getPagingManager()).andStubReturn(pm);
+      
       HierarchicalRepository<QueueSettings> qs = createStrictMock(HierarchicalRepository.class);
       ResourceManager rm = createStrictMock(ResourceManager.class);
       SecurityStore ss = createStrictMock(SecurityStore.class);
@@ -2361,13 +2453,13 @@
          expect(sm.generateTransactionID()).andReturn(71626L);
       }
 
-      replay(returner, sm, po, qs, rm, ss, pd, executor, server, cm);
+      replay(returner, sm, po, qs, rm, ss, pd, executor, server, cm, pm);
 
       ServerSession session = new ServerSessionImpl(id, "blah", null, null, true, false, xa,
                returner, server, sm, po, qs, rm, ss, pd, executor,
                cm);
 
-      verify(returner, sm, po, qs, rm, ss, pd, executor, server, cm);
+      verify(returner, sm, po, qs, rm, ss, pd, executor, server, cm, pm);
 
       assertEquals(id, session.getID());
    }

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/fakes/FakeQueueFactory.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/fakes/FakeQueueFactory.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/server/impl/fakes/FakeQueueFactory.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -29,6 +29,7 @@
 import org.jboss.messaging.core.server.Queue;
 import org.jboss.messaging.core.server.QueueFactory;
 import org.jboss.messaging.core.server.impl.QueueImpl;
+import org.jboss.messaging.core.settings.impl.QueueSettings;
 import org.jboss.messaging.util.SimpleString;
 
 /**
@@ -45,7 +46,7 @@
 	public Queue createQueue(long persistenceID, SimpleString name, Filter filter,
 			                   boolean durable)
 	{
-		return new QueueImpl(persistenceID, name, filter, false, durable, -1, scheduledExecutor);
+		return new QueueImpl(persistenceID, name, filter, false, durable, new QueueSettings(), scheduledExecutor);
 	}
 
 }

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/settings/impl/QueueSettingsTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/settings/impl/QueueSettingsTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/settings/impl/QueueSettingsTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -42,6 +42,7 @@
       assertEquals(queueSettings.getExpiryQueue(), null);
       assertEquals(queueSettings.getMaxDeliveryAttempts(), QueueSettings.DEFAULT_MAX_DELIVERY_ATTEMPTS);
       assertEquals(queueSettings.getMaxSizeBytes(), QueueSettings.DEFAULT_MAX_SIZE_BYTES);
+      assertEquals(queueSettings.getPageSizeBytes(), QueueSettings.DEFAULT_PAGE_SIZE_BYTES);
       assertEquals(queueSettings.getMessageCounterHistoryDayLimit(), QueueSettings.DEFAULT_MESSAGE_COUNTER_HISTORY_DAY_LIMIT);
       assertEquals(queueSettings.getRedeliveryDelay(), QueueSettings.DEFAULT_REDELIVER_DELAY);
 
@@ -57,9 +58,11 @@
       queueSettingsToMerge.setDLQ(DLQ);
       queueSettingsToMerge.setExpiryQueue(exp);
       queueSettingsToMerge.setMaxDeliveryAttempts(1000);
+      queueSettingsToMerge.setDropMessagesWhenFull(true);
       queueSettingsToMerge.setMaxSizeBytes(1001);
       queueSettingsToMerge.setMessageCounterHistoryDayLimit(1002);
       queueSettingsToMerge.setRedeliveryDelay((long)1003);
+      queueSettingsToMerge.setPageSizeBytes(1004);
       queueSettings.merge(queueSettingsToMerge);
       assertEquals(queueSettings.getDistributionPolicy().getClass(), QueueSettings.DEFAULT_DISTRIBUTION_POLICY.getClass());
       assertEquals(queueSettings.getDistributionPolicyClass(), null);
@@ -70,6 +73,8 @@
       assertEquals(queueSettings.getMaxSizeBytes(), Integer.valueOf(1001));
       assertEquals(queueSettings.getMessageCounterHistoryDayLimit(), Integer.valueOf(1002));
       assertEquals(queueSettings.getRedeliveryDelay(), Long.valueOf(1003));
+      assertEquals(queueSettings.getPageSizeBytes(), (Integer)1004);
+      assertTrue(queueSettings.isDropMessagesWhenFull());
    }
 
    public void testMultipleMerge()

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/core/transaction/impl/TransactionImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/transaction/impl/TransactionImplTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/transaction/impl/TransactionImplTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -512,13 +512,13 @@
    public void testAckCommit() throws Exception
    {
       //Durable queue
-      Queue queue1 = new QueueImpl(12, new SimpleString("queue1"), null, false, true, -1, scheduledExecutor);
+      Queue queue1 = new QueueImpl(12, new SimpleString("queue1"), null, false, true, new QueueSettings(), scheduledExecutor);
       
       //Durable queue
-      Queue queue2 = new QueueImpl(34, new SimpleString("queue2"), null, false, true, -1, scheduledExecutor);
+      Queue queue2 = new QueueImpl(34, new SimpleString("queue2"), null, false, true, new QueueSettings(), scheduledExecutor);
       
       //Non durable queue
-      Queue queue3 = new QueueImpl(65, new SimpleString("queue3"), null, false, false, -1, scheduledExecutor);
+      Queue queue3 = new QueueImpl(65, new SimpleString("queue3"), null, false, false, new QueueSettings(), scheduledExecutor);
       
       //Some refs to ack
       

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/jms/server/management/impl/JMSQueueControlTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/jms/server/management/impl/JMSQueueControlTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/jms/server/management/impl/JMSQueueControlTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -203,19 +203,6 @@
       verifyMockedAttributes();
    }
 
-   public void testGetMaxSizeBytes() throws Exception
-   {
-      int size = randomInt();
-
-      expect(coreQueue.getMaxSizeBytes()).andReturn(size);
-      replayMockedAttributes();
-
-      JMSQueueControl control = createControl();
-      assertEquals(size, control.getMaxSizeBytes());
-
-      verifyMockedAttributes();
-   }
-
    public void testGetSizeBytes() throws Exception
    {
       int size = randomInt();

Modified: trunk/tests/src/org/jboss/messaging/tests/unit/jms/server/management/impl/TopicControlTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/jms/server/management/impl/TopicControlTest.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/jms/server/management/impl/TopicControlTest.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -41,6 +41,7 @@
 import org.jboss.messaging.core.postoffice.Binding;
 import org.jboss.messaging.core.postoffice.PostOffice;
 import org.jboss.messaging.core.server.Queue;
+import org.jboss.messaging.core.settings.impl.QueueSettings;
 import org.jboss.messaging.jms.JBossTopic;
 import org.jboss.messaging.jms.server.management.SubscriptionInfo;
 import org.jboss.messaging.jms.server.management.impl.TopicControl;
@@ -283,24 +284,26 @@
       JBossTopic topic = new JBossTopic(name);
       PostOffice postOffice = createMock(PostOffice.class);
       StorageManager storageManager = createMock(StorageManager.class);
+      
+      QueueSettings settings = new QueueSettings();
 
       Queue durableQueue = createMock(Queue.class);
+      expect(durableQueue.getSettings()).andStubReturn(settings);
       expect(durableQueue.getName()).andStubReturn(
             JBossTopic.createAddressFromName(randomString()));
       expect(durableQueue.getFilter()).andStubReturn(null);
       expect(durableQueue.isDurable()).andStubReturn(true);
       expect(durableQueue.getMessageCount()).andStubReturn(randomInt());
-      expect(durableQueue.getMaxSizeBytes()).andStubReturn(randomInt());
       Binding bindingForDurableQueue = createMock(Binding.class);
       expect(bindingForDurableQueue.getQueue()).andStubReturn(durableQueue);
 
       Queue nonDurableQueue = createMock(Queue.class);
+      expect(nonDurableQueue.getSettings()).andStubReturn(settings);
       expect(nonDurableQueue.getName()).andStubReturn(
             JBossTopic.createAddressFromName(randomString()));
       expect(nonDurableQueue.getFilter()).andStubReturn(null);
       expect(nonDurableQueue.isDurable()).andStubReturn(false);
       expect(nonDurableQueue.getMessageCount()).andStubReturn(randomInt());
-      expect(nonDurableQueue.getMaxSizeBytes()).andStubReturn(randomInt());
       Binding bindingForNonDurableQueue = createMock(Binding.class);
       expect(bindingForNonDurableQueue.getQueue()).andStubReturn(nonDurableQueue);
       List<Binding> bindings = new ArrayList<Binding>();
@@ -331,27 +334,30 @@
       String jndiBinding = randomString();
       String name = randomString();
 
+      
+      QueueSettings settings = new QueueSettings();
+
       JBossTopic topic = new JBossTopic(name);
       PostOffice postOffice = createMock(PostOffice.class);
       StorageManager storageManager = createMock(StorageManager.class);
 
       Queue durableQueue = createMock(Queue.class);
+      expect(durableQueue.getSettings()).andStubReturn(settings);
       expect(durableQueue.getName()).andStubReturn(
             JBossTopic.createAddressFromName(randomString()));
       expect(durableQueue.getFilter()).andStubReturn(null);
       expect(durableQueue.isDurable()).andStubReturn(true);
       expect(durableQueue.getMessageCount()).andStubReturn(randomInt());
-      expect(durableQueue.getMaxSizeBytes()).andStubReturn(randomInt());
       Binding bindingForDurableQueue = createMock(Binding.class);
       expect(bindingForDurableQueue.getQueue()).andStubReturn(durableQueue);
 
       Queue nonDurableQueue = createMock(Queue.class);
+      expect(nonDurableQueue.getSettings()).andStubReturn(settings);
       expect(nonDurableQueue.getName()).andStubReturn(
             JBossTopic.createAddressFromName(randomString()));
       expect(nonDurableQueue.getFilter()).andStubReturn(null);
       expect(nonDurableQueue.isDurable()).andStubReturn(false);
       expect(nonDurableQueue.getMessageCount()).andStubReturn(randomInt());
-      expect(nonDurableQueue.getMaxSizeBytes()).andStubReturn(randomInt());
       Binding bindingForNonDurableQueue = createMock(Binding.class);
       expect(bindingForNonDurableQueue.getQueue()).andStubReturn(nonDurableQueue);
 

Modified: trunk/tests/src/org/jboss/messaging/tests/util/RandomUtil.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/util/RandomUtil.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/util/RandomUtil.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -72,6 +72,12 @@
       return random.nextInt();
    }
    
+   public static int randomPositiveInt()
+   {
+      final int value = randomInt();
+      return value >= 0 ? value : value * -1;
+   }
+   
    public static short randomShort()
    {
       return (short) random.nextInt(Short.MAX_VALUE);

Modified: trunk/tests/src/org/jboss/messaging/tests/util/UnitTestCase.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/util/UnitTestCase.java	2008-09-03 18:55:33 UTC (rev 4903)
+++ trunk/tests/src/org/jboss/messaging/tests/util/UnitTestCase.java	2008-09-04 02:35:13 UTC (rev 4904)
@@ -234,7 +234,49 @@
       return buffer.array();
    }
    
+   
+   protected ByteBuffer compareByteBuffer(final byte expectedArray[])
+   {
+      
+      EasyMock.reportMatcher(new IArgumentMatcher()
+      {
 
+         public void appendTo(StringBuffer buffer)
+         {
+            buffer.append("ByteArray");
+         }
+
+         public boolean matches(Object argument)
+         {
+            ByteBuffer buffer = (ByteBuffer) argument;
+            
+            buffer.rewind();
+            byte[] compareArray = new byte[buffer.limit()];
+            buffer.get(compareArray);
+            
+            if (compareArray.length != expectedArray.length)
+            {
+               return false;
+            }
+            
+            for (int i = 0; i < expectedArray.length; i++)
+            {
+               if (expectedArray[i] != compareArray[i])
+               {
+                  return false;
+               }
+            }
+            
+            return true;
+         }
+         
+      });
+      
+      return null;
+   }
+
+   
+
    protected boolean deleteDirectory(File directory)
    {
       if (directory.isDirectory())




More information about the jboss-cvs-commits mailing list