http://git-wip-us.apache.org/repos/asf/wicket/blob/c43d3a33/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializingPageStore.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializingPageStore.java
 
b/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializingPageStore.java
new file mode 100644
index 0000000..70c93e4
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializingPageStore.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.pageStore;
+
+import org.apache.wicket.page.IManageablePage;
+import org.apache.wicket.serialize.ISerializer;
+import org.apache.wicket.util.lang.Args;
+
+/**
+ * A store that serializes all pages before delegating and vice versa.
+ */
+public class SerializingPageStore extends DelegatingPageStore
+{
+
+       private ISerializer serializer;
+
+       /**
+        * @param delegate
+        *            store to delegate to
+        * @param serializer
+        *            serializer to use if session gets persisted
+        */
+       public SerializingPageStore(IPageStore delegate, ISerializer serializer)
+       {
+               super(delegate);
+
+               this.serializer = Args.notNull(serializer, "serializer");
+       }
+
+       /**
+        * Supports asynchronous add if the delegate supports it.
+        */
+       @Override
+       public boolean canBeAsynchronous(IPageContext context)
+       {
+               return getDelegate().canBeAsynchronous(context);
+       }
+       
+       @Override
+       public IManageablePage getPage(IPageContext context, int id)
+       {
+               IManageablePage page = super.getPage(context, id);
+
+               if (page instanceof SerializedPage) {
+                       page = 
(IManageablePage)serializer.deserialize(((SerializedPage)page).getData());
+               }
+               return page;
+       }
+
+       @Override
+       public void addPage(IPageContext context, IManageablePage page)
+       {
+               if (page instanceof SerializedPage == false) {
+                       page = new SerializedPage(page.getPageId(), 
page.getClass().getName(), serializer.serialize(page));
+               }
+               super.addPage(context, page);
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/c43d3a33/wicket-core/src/main/java/org/apache/wicket/pageStore/disk/NestedFolders.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/disk/NestedFolders.java 
b/wicket-core/src/main/java/org/apache/wicket/pageStore/disk/NestedFolders.java
new file mode 100644
index 0000000..0f2077c
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/pageStore/disk/NestedFolders.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.pageStore.disk;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.wicket.util.file.Files;
+import org.apache.wicket.util.lang.Args;
+
+/**
+ * Helps creating nested folders.
+ * 
+ * @author svenmeier
+ */
+public class NestedFolders
+{
+       private final File base;
+       
+       /**
+        * Create folders in the given base folder.
+        * 
+        * @param base base has to be a folder
+        */
+       public NestedFolders(File base) {
+               this.base = Args.notNull(base, "base");
+       }
+       
+       public File getBase()
+       {
+               return base;
+       }
+       
+       /**
+        * Get a nested folder for the given name.
+        * 
+        * @param name name 
+        * @param create
+        * @return
+        */
+       public File get(String name, final boolean create) {
+               name = name.replace('*', '_');
+               name = name.replace('/', '_');
+               name = name.replace(':', '_');
+
+               String path = createPathFrom(name);
+
+               File folder = new File(base, path);
+               if (create && folder.exists() == false) {
+                       Files.mkdirs(folder);
+               }
+               return folder;
+       }
+
+       private String createPathFrom(final String name) {
+               int hash = Math.abs(name.hashCode());
+               String low = String.valueOf(hash % 9973);
+               String high = String.valueOf((hash / 9973) % 9973);
+               StringBuilder bs = new StringBuilder(name.length() + 10);
+               bs.append(low);
+               bs.append(File.separator);
+               bs.append(high);
+               bs.append(File.separator);
+               bs.append(name);
+
+               return bs.toString();
+       }
+
+       /**
+        * Remove a nested folder.
+        * 
+        * @param name name of folder
+        */
+       public void remove(String name)
+       {
+               File folder = get(name, false);
+               if (folder.exists()) {
+                       Files.removeFolder(folder);
+                       
+                       File high = folder.getParentFile();
+                       if (high.list().length == 0) {
+                               if (Files.removeFolder(high)) {
+                                       File low = high.getParentFile();
+                                       if (low.list().length == 0) {
+                                               Files.removeFolder(low);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       public Set<File> getAll()
+       {
+               Set<File> files = new HashSet<>();
+               
+               if (base.exists()) {
+                       for (File low : base.listFiles()) {
+                               for (File high: low.listFiles()) {
+                                       for (File file : high.listFiles()) {
+                                               files.add(file);
+                                       }
+                               }
+                       }
+               }
+               
+               return files;
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/c43d3a33/wicket-core/src/main/java/org/apache/wicket/pageStore/disk/PageWindowManager.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/disk/PageWindowManager.java
 
b/wicket-core/src/main/java/org/apache/wicket/pageStore/disk/PageWindowManager.java
new file mode 100644
index 0000000..f20d156
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/pageStore/disk/PageWindowManager.java
@@ -0,0 +1,493 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.pageStore.disk;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.wicket.pageStore.IPersistedPage;
+import org.apache.wicket.util.collections.IntHashMap;
+import org.apache.wicket.util.lang.Bytes;
+
+/**
+ * Manages positions and size of chunks of data in a file.
+ * <p>
+ * The data is stored inside the file in a cyclic way. Newer pages are placed 
after older ones,
+ * until the maximum file size is reached. After that, the next page is stored 
in the beginning of
+ * the file.
+ * 
+ * @author Matej Knopp
+ */
+public class PageWindowManager implements Serializable
+{
+       private static final long serialVersionUID = 1L;
+
+       /**
+        * Contains information about a page inside the file.
+        * 
+        * @author Matej Knopp
+        */
+       public static class FileWindow implements IPersistedPage, Serializable
+       {
+               private static final long serialVersionUID = 1L;
+
+               /** id of data or -1 if the window is empty */
+               private int id;
+
+               private String type;
+
+               /** offset in the file where the serialized page data begins */
+               private int filePartOffset;
+
+               /** size of serialized page data */
+               private int filePartSize;
+
+               @Override
+               public int getPageId()
+               {
+                       return id;
+               }
+
+               @Override
+               public String getPageType() {
+                       return type;
+               }
+               
+               @Override
+               public Bytes getPageSize()
+               {
+                       return Bytes.bytes(filePartSize);
+               }
+
+               public int getFilePartOffset()
+               {
+                       return filePartOffset;
+               }
+               
+               public int getFilePartSize()
+               {
+                       return filePartSize;
+               }
+       }
+
+       private final List<FileWindow> windows = new ArrayList<FileWindow>();
+
+       /**
+        * map from page id to list of pagewindow indices (referring to the 
windows list) - to improve
+        * searching speed the index must be cleaned when the instances in the 
windows list change their
+        * indexes (e.g. items are shifted on page window removal)
+        */
+       private IntHashMap<Integer> idToWindowIndex = null;
+
+       /**
+        * Inversed index of #idToWindowIndex
+        */
+       private IntHashMap<Integer> windowIndexToPageId = null;
+
+       /** index of last added page */
+       private int indexPointer = -1;
+
+       private int totalSize = 0;
+
+       /**
+        * Maximum page size. After this size is exceeded, the pages will be 
saved starting at the
+        * beginning of file.
+        */
+       private final long maxSize;
+
+       /**
+        * 
+        * @param pageId
+        * @param windowIndex
+        */
+       private void putWindowIndex(int pageId, int windowIndex)
+       {
+               if (idToWindowIndex != null && pageId != -1 && windowIndex != 
-1)
+               {
+                       Integer oldPageId = 
windowIndexToPageId.remove(windowIndex);
+                       if (oldPageId != null)
+                       {
+                               idToWindowIndex.remove(oldPageId);
+                       }
+                       idToWindowIndex.put(pageId, windowIndex);
+                       windowIndexToPageId.put(windowIndex, pageId);
+               }
+       }
+
+       /**
+        * 
+        * @param pageId
+        */
+       private void removeWindowIndex(int pageId)
+       {
+               Integer windowIndex = idToWindowIndex.remove(pageId);
+               if (windowIndex != null)
+               {
+                       windowIndexToPageId.remove(windowIndex);
+               }
+       }
+
+       /**
+        * 
+        */
+       private void rebuildIndices()
+       {
+               idToWindowIndex = null;
+               idToWindowIndex = new IntHashMap<Integer>();
+               windowIndexToPageId = null;
+               windowIndexToPageId = new IntHashMap<Integer>();
+               for (int i = 0; i < windows.size(); ++i)
+               {
+                       FileWindow window = windows.get(i);
+                       putWindowIndex(window.id, i);
+               }
+       }
+
+       /**
+        * Returns the index of the given page in the {@link #windows} list.
+        * 
+        * @param pageId
+        * @return window index
+        */
+       private int getWindowIndex(int pageId)
+       {
+               if (idToWindowIndex == null)
+               {
+                       rebuildIndices();
+               }
+
+               Integer result = idToWindowIndex.get(pageId);
+               return result != null ? result : -1;
+       }
+
+       /**
+        * Increments the {@link #indexPointer}. If the maximum file size has 
been reached, the
+        * {@link #indexPointer} is set to 0.
+        * 
+        * @return new index pointer
+        */
+       private int incrementIndexPointer()
+       {
+               if ((maxSize > 0) && (totalSize >= maxSize) && (indexPointer == 
windows.size() - 1))
+               {
+                       indexPointer = 0;
+               }
+               else
+               {
+                       ++indexPointer;
+               }
+               return indexPointer;
+       }
+
+       /**
+        * Returns the offset in file of the window on given index. The offset 
is counted by getting the
+        * previous page offset and adding the previous page size to it.
+        * 
+        * @param index
+        * @return window file offset
+        */
+       private int getWindowFileOffset(int index)
+       {
+               if (index > 0)
+               {
+                       FileWindow window = windows.get(index - 1);
+                       return window.filePartOffset + window.filePartSize;
+               }
+               return 0;
+       }
+
+       /**
+        * Splits the window with given index to two windows. First of those 
will have size specified by
+        * the argument, the other one will fill up the rest of the original 
window.
+        * 
+        * @param index
+        * @param size
+        */
+       private void splitWindow(int index, int size)
+       {
+               FileWindow window = windows.get(index);
+               int delta = window.filePartSize - size;
+
+               if (index == windows.size() - 1)
+               {
+                       // if this is last window
+                       totalSize -= delta;
+                       window.filePartSize = size;
+               }
+               else if (window.filePartSize != size)
+               {
+                       FileWindow newWindow = new FileWindow();
+                       newWindow.id = -1;
+                       window.filePartSize = size;
+
+                       windows.add(index + 1, newWindow);
+
+                       newWindow.filePartOffset = getWindowFileOffset(index + 
1);
+                       newWindow.filePartSize = delta;
+               }
+
+               idToWindowIndex = null;
+               windowIndexToPageId = null;
+       }
+
+       /**
+        * Merges the window with given index with the next window. The 
resulting window will have size
+        * of the two windows summed together.
+        * 
+        * @param index
+        */
+       private void mergeWindowWithNext(int index)
+       {
+               if (index < windows.size() - 1)
+               {
+                       FileWindow window = windows.get(index);
+                       FileWindow next = windows.get(index + 1);
+                       window.filePartSize += next.filePartSize;
+
+                       windows.remove(index + 1);
+                       idToWindowIndex = null; // reset index
+                       windowIndexToPageId = null;
+               }
+       }
+
+       /**
+        * Adjusts the window on given index to the specified size. If the new 
size is smaller than the
+        * window size, the window will be split. Otherwise the window will be 
merged with as many
+        * subsequent window as necessary. In case the window is last window in 
the file, the size will
+        * be adjusted without splitting or merging.
+        * 
+        * @param index
+        * @param size
+        */
+       private void adjustWindowSize(int index, int size)
+       {
+               FileWindow window = windows.get(index);
+
+               // last window, just adjust size
+               if (index == windows.size() - 1)
+               {
+                       int delta = size - window.filePartSize;
+                       totalSize += delta;
+                       window.filePartSize = size;
+               }
+               else
+               {
+                       // merge as many times as necessary
+                       while (window.filePartSize < size && index < 
windows.size() - 1)
+                       {
+                               mergeWindowWithNext(index);
+                       }
+
+                       // done merging - do we have enough room ?
+                       if (window.filePartSize < size)
+                       {
+                               // no, this is the last window
+                               int delta = size - window.filePartSize;
+                               totalSize += delta;
+                               window.filePartSize = size;
+                       }
+                       else
+                       {
+                               // yes, we might want to split the window, so 
that we don't lose
+                               // space when the created window was too big
+                               splitWindow(index, size);
+                       }
+               }
+
+               window.id = -1;
+       }
+
+       /**
+        * Allocates window on given index with to size. If the index is 
pointing to existing window,
+        * the window size will be adjusted. Otherwise a new window with 
appropriated size will be
+        * created.
+        * 
+        * @param index
+        * @param size
+        * @return page window
+        */
+       private FileWindow allocatePageWindow(int index, int size)
+       {
+               final FileWindow window;
+
+               // new window
+               if (index == windows.size())
+               {
+                       // new page window
+                       window = new FileWindow();
+                       window.filePartOffset = getWindowFileOffset(index);
+                       totalSize += size;
+                       window.filePartSize = size;
+                       windows.add(window);
+               }
+               else
+               {
+                       // get the window
+                       window = windows.get(index);
+
+                       // adjust if necessary
+                       if (window.filePartSize != size)
+                       {
+                               adjustWindowSize(index, size);
+                       }
+               }
+
+               return window;
+       }
+
+       /**
+        * Creates and returns a new page window for given page.
+        * 
+        * @param pageId
+        * @param type 
+        * @param size
+        * @return page window
+        */
+       public synchronized FileWindow createPageWindow(int pageId, String 
pageType, int size)
+       {
+               int index = getWindowIndex(pageId);
+
+               // if we found the page window, mark it as invalid
+               if (index != -1)
+               {
+                       removeWindowIndex(pageId);
+                       (windows.get(index)).id = -1;
+               }
+
+               // if we are not going to reuse a page window (because it's not 
on
+               // indexPointer position or because we didn't find it), 
increment the
+               // indexPointer
+               if (index == -1 || index != indexPointer)
+               {
+                       index = incrementIndexPointer();
+               }
+
+               FileWindow window = allocatePageWindow(index, size);
+               window.id = pageId;
+               window.type = pageType;
+
+               putWindowIndex(pageId, index);
+               return window;
+       }
+
+       /**
+        * Returns the page window for given page or null if no window was 
found.
+        * 
+        * @param pageId
+        * @return page window or null
+        */
+       public synchronized FileWindow getPageWindow(int pageId)
+       {
+               int index = getWindowIndex(pageId);
+               if (index != -1)
+               {
+                       return windows.get(index);
+               }
+               return null;
+       }
+
+       /**
+        * Removes the page window for given page.
+        * 
+        * @param pageId
+        */
+       public synchronized void removePage(int pageId)
+       {
+               int index = getWindowIndex(pageId);
+               if (index != -1)
+               {
+                       FileWindow window = windows.get(index);
+                       removeWindowIndex(pageId);
+                       if (index == windows.size() - 1)
+                       {
+                               windows.remove(index);
+                               totalSize -= window.filePartSize;
+                               if (indexPointer == index)
+                               {
+                                       --indexPointer;
+                               }
+                       }
+                       else
+                       {
+                               window.id = -1;
+                       }
+               }
+       }
+
+       /**
+        * Returns last n saved page windows.
+        * 
+        * @return list of page windows
+        */
+       public synchronized List<FileWindow> getFileWindows()
+       {
+               List<FileWindow> result = new ArrayList<FileWindow>();
+
+               // start from current index to 0
+               int currentIndex = indexPointer;
+
+               do
+               {
+                       if (currentIndex == -1)
+                       {
+                               break;
+                       }
+
+                       if (currentIndex < windows.size())
+                       {
+                               FileWindow window = windows.get(currentIndex);
+                               if (window.id != -1)
+                               {
+                                       result.add(window);
+                               }
+                       }
+
+                       --currentIndex;
+                       if (currentIndex == -1)
+                       {
+                               // rewind to the last entry and collect all 
entries until current index
+                               currentIndex = windows.size() - 1;
+                       }
+               }
+               while (currentIndex != indexPointer);
+
+               return result;
+       }
+
+       /**
+        * Creates a new PageWindowManager.
+        * 
+        * @param maxSize
+        *            maximum page size. After this size is exceeded, the pages 
will be saved starting
+        *            at the beginning of file
+        */
+       public PageWindowManager(long maxSize)
+       {
+               this.maxSize = maxSize;
+       }
+
+       /**
+        * Returns the size of all saved pages
+        * 
+        * @return total size
+        */
+       public synchronized int getTotalSize()
+       {
+               return totalSize;
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/c43d3a33/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/HttpSessionDataStore.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/HttpSessionDataStore.java
 
b/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/HttpSessionDataStore.java
deleted file mode 100644
index fcc4f7a..0000000
--- 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/HttpSessionDataStore.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.pageStore.memory;
-
-import javax.servlet.http.HttpSession;
-
-import org.apache.wicket.Session;
-import org.apache.wicket.page.IPageManagerContext;
-import org.apache.wicket.pageStore.IDataStore;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A {@link IDataStore} which stores the pages in the {@link HttpSession}. Uses
- * {@link IDataStoreEvictionStrategy} to keep the memory footprint reasonable.
- *
- * <p>
- * Usage:
- *
- * <pre>
- * <!--@formatter:off-->
- * MyApp#init()
- * {
- *
- *     setPageManagerProvider(new DefaultPageManagerProvider(this)
- *     {
- *             protected IDataStore newDataStore() 
- *             { 
- *                     return  new HttpSessionDataStore(pageManagerContext, 
new PageNumberEvictionStrategy(20));
- *             }
- *     }
- * }
- * <!--@formatter:on-->
- * </pre>
- */
-public class HttpSessionDataStore implements IDataStore
-{
-       private static final Logger LOG = 
LoggerFactory.getLogger(HttpSessionDataStore.class);
-
-       /** the session attribute key. auto-prefixed with 
application.getSessionAttributePrefix() */
-       private static final String PAGE_TABLE_KEY = "page:store:memory";
-
-       private final IPageManagerContext pageManagerContext;
-
-       private final IDataStoreEvictionStrategy evictionStrategy;
-
-       /**
-        * Construct.
-        * 
-        * @param pageManagerContext
-        * @param evictionStrategy
-        */
-       public HttpSessionDataStore(IPageManagerContext pageManagerContext,
-               IDataStoreEvictionStrategy evictionStrategy)
-       {
-               this.pageManagerContext = pageManagerContext;
-               this.evictionStrategy = evictionStrategy;
-       }
-
-       /**
-        * @param sessionId
-        *            Ignored. Only pages from the current http session can be 
read
-        * @see 
org.apache.wicket.pageStore.IDataStore#getData(java.lang.String, int)
-        */
-       @Override
-       public byte[] getData(String sessionId, int pageId)
-       {
-               PageTable pageTable = getPageTable(false, false);
-               byte[] pageAsBytes = null;
-               if (pageTable != null)
-               {
-                       pageAsBytes = pageTable.getPage(pageId);
-               }
-
-               if (LOG.isDebugEnabled())
-               {
-                       int bytesLength = pageAsBytes != null ? 
pageAsBytes.length : -1;
-                       LOG.debug("Loaded '{}' bytes for page with id '{}' in 
session '{}'",
-                                       bytesLength, pageId, sessionId);
-               }
-
-
-               return pageAsBytes;
-       }
-
-       @Override
-       public void removeData(String sessionId, int pageId)
-       {
-               PageTable pageTable = getPageTable(false, true);
-               if (pageTable != null)
-               {
-                       byte[] bytes = pageTable.removePage(pageId);
-
-                       if (LOG.isDebugEnabled() && bytes != null)
-                       {
-                               LOG.debug("Removed page '{}' in session '{}'", 
pageId, sessionId);
-                       }
-               }
-       }
-
-       @Override
-       public void removeData(String sessionId)
-       {
-               PageTable pageTable = getPageTable(false, true);
-               if (pageTable != null)
-               {
-                       pageTable.clear();
-                       LOG.debug("Removed all pages in session '{}'", 
sessionId);
-               }
-       }
-
-       @Override
-       public void storeData(String sessionId, int pageId, byte[] pageAsBytes)
-       {
-               PageTable pageTable = getPageTable(true, true);
-               if (pageTable != null)
-               {
-                       pageTable.storePage(pageId, pageAsBytes);
-                       if (LOG.isDebugEnabled())
-                       {
-                               LOG.debug("Stored '{}' bytes for page '{}' in 
session '{}'",
-                                               pageAsBytes.length, pageId, 
sessionId);
-                       }
-                       evictionStrategy.evict(pageTable);
-               }
-               else
-               {
-                       LOG.error("Cannot store the data for page with id '{}' 
in session with id '{}'",
-                               pageId, sessionId);
-               }
-       }
-
-       @Override
-       public void destroy()
-       {
-               // do nothing
-               // this is application lifecycle thread (WicketFilter#destroy())
-               // so there is no reachable http session
-       }
-
-       @Override
-       public boolean isReplicated()
-       {
-               return true;
-       }
-
-       private PageTable getPageTable(boolean create, boolean rewriteToSession)
-       {
-               PageTable pageTable = null;
-               if (Session.exists())
-               {
-                       pageTable = 
(PageTable)pageManagerContext.getSessionAttribute(PAGE_TABLE_KEY);
-                       if (pageTable == null && create)
-                       {
-                               pageTable = new PageTable();
-                               
pageManagerContext.setSessionAttribute(PAGE_TABLE_KEY, pageTable);
-                       } else if (rewriteToSession) {
-                               
pageManagerContext.setSessionAttribute(PAGE_TABLE_KEY, pageTable);
-                       }
-               }
-               return pageTable;
-       }
-
-       @Override
-       public final boolean canBeAsynchronous()
-       {
-               // HttpSessionDataStore needs access to the current http session
-               // and this is not possible in AsychronousDataStore
-               return false;
-       }
-
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/c43d3a33/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/IDataStoreEvictionStrategy.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/IDataStoreEvictionStrategy.java
 
b/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/IDataStoreEvictionStrategy.java
deleted file mode 100644
index 6b6e556..0000000
--- 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/IDataStoreEvictionStrategy.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.pageStore.memory;
-
-
-/**
- * An eviction strategy that decides whether the in-memory data structure used 
as page store should
- * be compacted
- */
-@FunctionalInterface
-public interface IDataStoreEvictionStrategy
-{
-
-       /**
-        * Called after each {@link 
org.apache.wicket.pageStore.IDataStore#storeData(String, int, byte[])} call.
-        * 
-        * @param pageTable
-        *            the in-memory data store with <strong>all</strong> pages
-        */
-       void evict(PageTable pageTable);
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/c43d3a33/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/MemorySizeEvictionStrategy.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/MemorySizeEvictionStrategy.java
 
b/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/MemorySizeEvictionStrategy.java
deleted file mode 100644
index 92f985b..0000000
--- 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/MemorySizeEvictionStrategy.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.pageStore.memory;
-
-import org.apache.wicket.util.lang.Args;
-import org.apache.wicket.util.lang.Bytes;
-import org.apache.wicket.core.util.lang.WicketObjects;
-
-/**
- * An eviction strategy that keeps the data store size up to configured bytes
- */
-public class MemorySizeEvictionStrategy implements IDataStoreEvictionStrategy
-{
-
-       private final Bytes maxBytes;
-
-       /**
-        * Construct.
-        * 
-        * @param maxBytes
-        *            the maximum size of the data store
-        */
-       public MemorySizeEvictionStrategy(Bytes maxBytes)
-       {
-               Args.notNull(maxBytes, "maxBytes");
-
-               this.maxBytes = maxBytes;
-       }
-
-       /**
-        * 
-        * @see 
IDataStoreEvictionStrategy#evict(org.apache.wicket.pageStore.memory.PageTable)
-        */
-       @Override
-       public void evict(PageTable pageTable)
-       {
-
-               long storeCurrentSize = WicketObjects.sizeof(pageTable);
-
-               if (storeCurrentSize > maxBytes.bytes())
-               {
-                       PageTableCleaner cleaner = new PageTableCleaner();
-                       cleaner.drop(pageTable, 1);
-
-                       // recurse until enough space is cleaned
-                       evict(pageTable);
-               }
-       }
-
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/c43d3a33/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/PageNumberEvictionStrategy.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/PageNumberEvictionStrategy.java
 
b/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/PageNumberEvictionStrategy.java
deleted file mode 100644
index 9857a6b..0000000
--- 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/PageNumberEvictionStrategy.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.pageStore.memory;
-
-
-/**
- * An eviction strategy which decides whether to evict entries from the 
in-memory data store
- * depending on the number of stored paged per session
- */
-public class PageNumberEvictionStrategy implements IDataStoreEvictionStrategy
-{
-
-       private final int pagesNumber;
-
-       /**
-        * Construct.
-        * 
-        * @param pagesNumber
-        *            the maximum number of pages the data store can hold
-        */
-       public PageNumberEvictionStrategy(int pagesNumber)
-       {
-               if (pagesNumber < 1)
-               {
-                       throw new IllegalArgumentException("'pagesNumber' must 
be greater than 0.");
-               }
-
-               this.pagesNumber = pagesNumber;
-       }
-
-       /**
-        * 
-        * @see 
IDataStoreEvictionStrategy#evict(org.apache.wicket.pageStore.memory.PageTable)
-        */
-       @Override
-       public void evict(PageTable pageTable)
-       {
-               int size = pageTable.size();
-               int pagesToDrop = size - pagesNumber;
-
-               if (pagesToDrop > 0)
-               {
-                       PageTableCleaner cleaner = new PageTableCleaner();
-                       cleaner.drop(pageTable, pagesToDrop);
-               }
-       }
-
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/c43d3a33/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/PageTable.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/PageTable.java 
b/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/PageTable.java
deleted file mode 100644
index dfad4af..0000000
--- 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/PageTable.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.pageStore.memory;
-
-import java.util.Iterator;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ConcurrentMap;
-
-import org.apache.wicket.util.io.IClusterable;
-
-/**
- * A structure that holds page id => pageAsBytes.
- * 
- * <p>
- * Additionally it has an index of the least recently used pages
- */
-public class PageTable implements IClusterable
-{
-       private static final long serialVersionUID = 1L;
-
-       /**
-        * Holds the index of last/least recently used page ids. The most 
recently used page id is in
-        * the tail, the least recently used is in the head.
-        */
-       /*
-        * Can be replaced later with PriorityQueue to deal with lightweight 
(Ajax) and heavyweight
-        * pages
-        */
-       private final Queue<Integer> index;
-
-       /**
-        * The actual container for the pages.
-        * 
-        * <p>
-        * page id => page as bytes
-        */
-       private final ConcurrentMap<Integer, byte[]> pages;
-
-       public PageTable()
-       {
-               pages = new ConcurrentHashMap<>();
-               index = new ConcurrentLinkedQueue<>();
-       }
-
-       public void storePage(Integer pageId, byte[] pageAsBytes)
-       {
-               synchronized (index)
-               {
-                       pages.put(pageId, pageAsBytes);
-
-                       updateIndex(pageId);
-               }
-       }
-
-       public byte[] getPage(final Integer pageId)
-       {
-               synchronized (index)
-               {
-                       updateIndex(pageId);
-
-                       return pages.get(pageId);
-               }
-       }
-
-       public byte[] removePage(Integer pageId)
-       {
-               synchronized (index)
-               {
-                       index.remove(pageId);
-
-                       return pages.remove(pageId);
-               }
-       }
-
-       public void clear()
-       {
-               synchronized (index)
-               {
-                       index.clear();
-                       pages.clear();
-               }
-       }
-
-       public int size()
-       {
-               return pages.size();
-       }
-
-       public Integer getOldest()
-       {
-               return index.peek();
-       }
-
-       public Iterator<Integer> indexIterator()
-       {
-               return index.iterator();
-       }
-
-       /**
-        * Updates the index of last/least recently used pages by removing the 
page id from the index
-        * (in case it is already in) and (re-)adding it at the head
-        * 
-        * @param pageId
-        *            the id of a recently used page
-        */
-       private void updateIndex(Integer pageId)
-       {
-               index.remove(pageId);
-               index.offer(pageId);
-       }
-
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/c43d3a33/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/PageTableCleaner.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/PageTableCleaner.java
 
b/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/PageTableCleaner.java
deleted file mode 100644
index 2c9a9cb..0000000
--- 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/memory/PageTableCleaner.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.pageStore.memory;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Helper class that knows how to remove the nth oldest pages from {@link 
PageTable}
- */
-public class PageTableCleaner
-{
-       private static final Logger LOG = 
LoggerFactory.getLogger(PageTableCleaner.class);
-
-       /**
-        * Removes {@code pagesNumber} of pages from the {@link PageTable 
pageTable}
-        * 
-        * @param pageTable
-        *            the {@link PageTable} to clean
-        * @param pagesNumber
-        *            the number of pages to remove
-        */
-       public void drop(final PageTable pageTable, final int pagesNumber)
-       {
-               for (int i = 0; i < pagesNumber; i++)
-               {
-                       Integer pageIdOfTheOldest = pageTable.getOldest();
-                       pageTable.removePage(pageIdOfTheOldest);
-                       LOG.debug("Evicted page with id '{}' from the 
HttpSessionDataStore");
-               }
-       }
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/c43d3a33/wicket-core/src/main/java/org/apache/wicket/settings/StoreSettings.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/settings/StoreSettings.java 
b/wicket-core/src/main/java/org/apache/wicket/settings/StoreSettings.java
index 8852208..7c32101 100644
--- a/wicket-core/src/main/java/org/apache/wicket/settings/StoreSettings.java
+++ b/wicket-core/src/main/java/org/apache/wicket/settings/StoreSettings.java
@@ -26,9 +26,8 @@ import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.lang.Bytes;
 
 /**
- * A class for settings related to the the storages where page instances are 
persisted -
- * {@link org.apache.wicket.pageStore.IPageStore},
- * {@link org.apache.wicket.pageStore.IDataStore} and {@link 
org.apache.wicket.page.IPageManager}.
+ * A class for settings related to the the storages where page instances are 
persisted, used by
+ * {@link org.apache.wicket.pageStore.IPageStore} {@link 
org.apache.wicket.page.IPageManager}.
  * <p>
  * For more information about page storages read <a
  * href="https://cwiki.apache.org/confluence/x/qIaoAQ";>Page Storage - Wiki 
page</a>
@@ -38,28 +37,18 @@ import org.apache.wicket.util.lang.Bytes;
  */
 public class StoreSettings
 {
-       /**
-        * By default the second level cache is disabled.
-        *
-        * @see <a 
href="https://issues.apache.org/jira/browse/WICKET-5554";>WICKET-5554</a>
-        * @see <a href="https://cwiki.apache.org/confluence/x/qIaoAQ";>Wicket 
Page storages</a>
-        */
-       private static final int DEFAULT_CACHE_SIZE = 0;
-
        private static final Bytes DEFAULT_MAX_SIZE_PER_SESSION = 
Bytes.megabytes(10);
 
        private static final int DEFAULT_ASYNCHRONOUS_QUEUE_CAPACITY = 100;
 
-       private int inmemoryCacheSize = DEFAULT_CACHE_SIZE;
-
        private Bytes maxSizePerSession = DEFAULT_MAX_SIZE_PER_SESSION;
 
        private File fileStoreFolder = null;
 
        private int asynchronousQueueCapacity = 
DEFAULT_ASYNCHRONOUS_QUEUE_CAPACITY;
 
-       private boolean isAsynchronous = true;
-
+       private boolean asynchronous = true;
+       
        /**
         * Construct.
         * 
@@ -70,32 +59,8 @@ public class StoreSettings
        }
 
        /**
-        * @return the number of page instances which will be stored in the 
application scoped cache for
-        *         faster retrieval
-        */
-       public int getInmemoryCacheSize()
-       {
-               return inmemoryCacheSize;
-       }
-
-       /**
-        * Sets the maximum number of page instances which will be stored in 
the application scoped
-        * second level cache for faster retrieval
-        *
-        * @param inmemoryCacheSize
-        *            the maximum number of page instances which will be held 
in the application scoped
-        *            cache
-        * @return {@code this} object for chaining
-        */
-       public StoreSettings setInmemoryCacheSize(int inmemoryCacheSize)
-       {
-               this.inmemoryCacheSize = inmemoryCacheSize;
-               return this;
-       }
-
-       /**
         * @return maximum page size. After this size is exceeded,
-        * the {@link org.apache.wicket.pageStore.DiskDataStore} will start 
saving the
+        * the {@link org.apache.wicket.pageStore.DiskPageStore} will start 
saving the
         * pages at the beginning of file.
         */
        public Bytes getMaxSizePerSession()
@@ -105,7 +70,7 @@ public class StoreSettings
 
        /**
         * Sets the maximum size of the {@link File} where page instances per 
session are stored. After
-        * reaching this size the {@link 
org.apache.wicket.pageStore.DiskDataStore} will start overriding the
+        * reaching this size the {@link 
org.apache.wicket.pageStore.DiskPageStore} will start overriding the
         * oldest pages at the beginning of the file.
         *
         * @param maxSizePerSession
@@ -120,7 +85,7 @@ public class StoreSettings
        }
 
        /**
-        * @return the location of the folder where {@link 
org.apache.wicket.pageStore.DiskDataStore} will store the files with page
+        * @return the location of the folder where {@link 
org.apache.wicket.pageStore.DiskPageStore} will store the files with page
         *         instances per session
         */
        public File getFileStoreFolder()
@@ -151,7 +116,7 @@ public class StoreSettings
        }
 
        /**
-        * Sets the folder where {@link 
org.apache.wicket.pageStore.DiskDataStore} will store the files with page 
instances per
+        * Sets the folder where {@link 
org.apache.wicket.pageStore.DiskPageStore} will store the files with page 
instances per
         * session
         *
         * @param fileStoreFolder
@@ -166,7 +131,7 @@ public class StoreSettings
 
        /**
         * @return the capacity of the queue used to store the pages which will 
be stored asynchronously
-        * @see org.apache.wicket.pageStore.AsynchronousDataStore
+        * @see org.apache.wicket.pageStore.AsynchronousPageStore
         */
        public int getAsynchronousQueueCapacity()
        {
@@ -178,7 +143,7 @@ public class StoreSettings
         *
         * @param queueCapacity
         *            the capacity of the queue
-        * @see org.apache.wicket.pageStore.AsynchronousDataStore
+        * @see org.apache.wicket.pageStore.AsynchronousPageStore
         * @return {@code this} object for chaining
         */
        public StoreSettings setAsynchronousQueueCapacity(int queueCapacity)
@@ -193,9 +158,9 @@ public class StoreSettings
        }
 
        /**
-        * Sets a flag whether to wrap the configured {@link 
org.apache.wicket.pageStore.IDataStore} with
-        * {@link org.apache.wicket.pageStore.AsynchronousDataStore}. By doing 
this the HTTP worker thread will not wait for the
-        * actual write of the page's bytes into the wrapped {@link 
org.apache.wicket.pageStore.IDataStore}.
+        * Sets a flag whether to wrap the configured {@link 
org.apache.wicket.pageStore.IPageStore} with
+        * {@link org.apache.wicket.pageStore.AsynchronousPageStore}. By doing 
this the HTTP worker thread will not wait for the
+        * actual write of the page's bytes into the wrapped {@link 
org.apache.wicket.pageStore.IPageStore}.
         *
         * @param async
         *            {@code true} to make it asynchronous, {@code false} - 
otherwise
@@ -203,15 +168,15 @@ public class StoreSettings
         */
        public StoreSettings setAsynchronous(boolean async)
        {
-               isAsynchronous = async;
+               asynchronous = async;
                return this;
        }
 
        /**
-        * @return {@code true} if the storing of page's bytes is asynchronous
+        * @return {@code true} if the storing of page is asynchronous
         */
        public boolean isAsynchronous()
        {
-               return isAsynchronous;
+               return asynchronous;
        }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/c43d3a33/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java 
b/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java
index d4de9f6..c84f1f5 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java
@@ -92,11 +92,11 @@ import org.apache.wicket.markup.html.list.ListView;
 import org.apache.wicket.markup.parser.XmlPullParser;
 import org.apache.wicket.markup.parser.XmlTag;
 import org.apache.wicket.mock.MockApplication;
-import org.apache.wicket.mock.MockPageManager;
+import org.apache.wicket.mock.MockPageStore;
 import org.apache.wicket.mock.MockRequestParameters;
 import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.page.IPageManager;
-import org.apache.wicket.page.IPageManagerContext;
+import org.apache.wicket.page.PageManager;
 import org.apache.wicket.protocol.http.AjaxEnclosureListener;
 import org.apache.wicket.protocol.http.IMetaDataBufferingWebResponse;
 import org.apache.wicket.protocol.http.WebApplication;
@@ -129,6 +129,7 @@ import 
org.apache.wicket.settings.RequestCycleSettings.RenderStrategy;
 import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.lang.Classes;
 import org.apache.wicket.util.lang.Generics;
+import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
 import org.apache.wicket.util.resource.StringResourceStream;
 import org.apache.wicket.util.string.Strings;
 import org.apache.wicket.util.time.Duration;
@@ -137,6 +138,8 @@ import org.apache.wicket.util.visit.IVisitor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import junit.framework.AssertionFailedError;
+
 /**
  * A helper class to ease unit testing of Wicket applications without the need 
for a servlet
  * container. See javadoc of <code>WicketTester</code> for example usage. This 
class can be used as
@@ -158,14 +161,19 @@ public class BaseWicketTester
        private static final Logger log = 
LoggerFactory.getLogger(BaseWicketTester.class);
 
        private final ServletContext servletContext;
-       private final WebApplication application;
-       private final List<MockHttpServletRequest> previousRequests = 
Generics.newArrayList();
-       private final List<MockHttpServletResponse> previousResponses = 
Generics.newArrayList();
        private MockHttpSession httpSession;
+
+       private final WebApplication application;
+
        private boolean followRedirects = true;
        private int redirectCount;
+
        private MockHttpServletRequest lastRequest;
        private MockHttpServletResponse lastResponse;
+
+       private final List<MockHttpServletRequest> previousRequests = 
Generics.newArrayList();
+       private final List<MockHttpServletResponse> previousResponses = 
Generics.newArrayList();
+
        /** current request and response */
        private MockHttpServletRequest request;
        private MockHttpServletResponse response;
@@ -281,8 +289,7 @@ public class BaseWicketTester
         * @param init
         *            force the application to be initialized (default = true)
         */
-       public BaseWicketTester(final WebApplication application, final 
ServletContext servletCtx,
-               boolean init)
+       public BaseWicketTester(final WebApplication application, final 
ServletContext servletCtx, boolean init)
        {
                if (!init)
                {
@@ -292,10 +299,10 @@ public class BaseWicketTester
                servletContext = servletCtx != null ? servletCtx
                        // If it's provided from the container it's not 
necessary to mock.
                        : !init && application.getServletContext() != null ? 
application.getServletContext()
-                               : new MockServletContext(application, null);
+                       : new MockServletContext(application, null);
 
                // If using Arquillian and it's configured in a web.xml it'll 
be provided. If not, mock it.
-               if (application.getWicketFilter() == null)
+               if(application.getWicketFilter() == null)
                {
                        final FilterConfig filterConfig = new 
TestFilterConfig();
                        WicketFilter filter = new WicketFilter()
@@ -334,16 +341,16 @@ public class BaseWicketTester
                
application.getResourceSettings().setResourcePollFrequency(getResourcePollFrequency());
 
                // reconfigure application for the test environment
-               application.setPageRendererProvider(
-                       new 
LastPageRecordingPageRendererProvider(application.getPageRendererProvider()));
-               application.setRequestCycleProvider(
-                       new 
TestRequestCycleProvider(application.getRequestCycleProvider()));
+               application.setPageRendererProvider(new 
LastPageRecordingPageRendererProvider(
+                       application.getPageRendererProvider()));
+               application.setRequestCycleProvider(new 
TestRequestCycleProvider(
+                       application.getRequestCycleProvider()));
 
                // set a feedback message filter that will not remove any 
messages
                originalFeedbackMessageCleanupFilter = 
application.getApplicationSettings()
                        .getFeedbackMessageCleanupFilter();
-               application.getApplicationSettings()
-                       
.setFeedbackMessageCleanupFilter(IFeedbackMessageFilter.NONE);
+               
application.getApplicationSettings().setFeedbackMessageCleanupFilter(
+                       IFeedbackMessageFilter.NONE);
                IPageManagerProvider pageManagerProvider = 
newTestPageManagerProvider();
                if (pageManagerProvider != null)
                {
@@ -386,8 +393,7 @@ public class BaseWicketTester
 
        private void setupNextRequestCycle()
        {
-               request = new MockHttpServletRequest(application, httpSession, 
servletContext,
-                       servletRequestLocale());
+               request = new MockHttpServletRequest(application, httpSession, 
servletContext, servletRequestLocale());
                request.setURL(request.getContextPath() + 
request.getServletPath() + "/");
 
                // assign protocol://host:port to next request unless the last 
request was ajax
@@ -408,8 +414,7 @@ public class BaseWicketTester
                // Preserve response cookies in redirects
                // XXX: is this really needed ? Browsers wont do that, but some
                // Wicket tests assert that a cookie is in the response,
-               // even after redirects (see
-               // 
org.apache.wicket.util.cookies.SetCookieAndRedirectTest.statefulPage())
+               // even after redirects (see 
org.apache.wicket.util.cookies.SetCookieAndRedirectTest.statefulPage())
                // They should assert that the cookie is in the next *request*
                if (lastResponse != null)
                {
@@ -466,8 +471,7 @@ public class BaseWicketTester
                }
        }
 
-       protected Locale servletRequestLocale()
-       {
+       protected Locale servletRequestLocale() {
                return Locale.getDefault();
        }
 
@@ -723,7 +727,7 @@ public class BaseWicketTester
                        {
                                if (redirectCount++ >= 100)
                                {
-                                       throw new AssertionError("Possible 
infinite redirect detected. Bailing out.");
+                                       fail("Possible infinite redirect 
detected. Bailing out.");
                                }
 
                                Url newUrl = 
Url.parse(lastResponse.getRedirectLocation(),
@@ -993,10 +997,11 @@ public class BaseWicketTester
         *
         * @return Wicket-Ajax-BaseURL set on last response by {@link 
AbstractDefaultAjaxBehavior}
         * @throws IOException
+        * @throws ResourceStreamNotFoundException
         * @throws ParseException
         */
-       public String getWicketAjaxBaseUrlEncodedInLastResponse()
-               throws IOException, ParseException
+       public String getWicketAjaxBaseUrlEncodedInLastResponse() throws 
IOException,
+               ResourceStreamNotFoundException, ParseException
        {
                XmlPullParser parser = new XmlPullParser();
                parser.parse(getLastResponseAsString());
@@ -1077,12 +1082,13 @@ public class BaseWicketTester
        }
 
        /**
-        * Simulates processing URL that invokes an {@link IRequestListener} on 
a component.
+        * Simulates processing URL that invokes an {@link IRequestListener} on 
a component.
         *
-        * After the listener is invoked the page containing the component will 
be rendered (with an
-        * optional redirect - depending on {@link RenderStrategy}).
+        * After the listener is invoked the page containing the component will 
be rendered
+        * (with an optional redirect - depending on {@link RenderStrategy}).
         *
         * @param component
+        * @param listener
         */
        public void executeListener(final Component component)
        {
@@ -1115,10 +1121,11 @@ public class BaseWicketTester
         * Simulates invoking an {@link IRequestListener} on a component. As 
opposed to the
         * {@link #executeListener(Component)} method, current request/response 
objects will be used
         *
-        * After the listener is invoked the page containing the component will 
be rendered (with an
-        * optional redirect - depending on {@link RenderStrategy}).
+        * After the listener is invoked the page containing the component will 
be rendered
+        * (with an optional redirect - depending on {@link RenderStrategy}).
         *
         * @param component
+        * @param listener
         */
        public void invokeListener(final Component component)
        {
@@ -1126,8 +1133,8 @@ public class BaseWicketTester
 
                // there are two ways to do this. RequestCycle could be forced 
to call the handler
                // directly but constructing and parsing the URL increases the 
chance of triggering bugs
-               IRequestHandler handler = new ListenerRequestHandler(
-                       new PageAndComponentProvider(component.getPage(), 
component));
+               IRequestHandler handler = new ListenerRequestHandler(new 
PageAndComponentProvider(
+                       component.getPage(), component));
 
                processRequest(handler);
        }
@@ -1136,11 +1143,11 @@ public class BaseWicketTester
         * Simulates invoking an {@link IRequestListener} on a component. As 
opposed to the
         * {@link #executeListener(Component)} method, current request/response 
objects will be used
         *
-        * After the listener is invoked the page containing the component will 
be rendered (with an
-        * optional redirect - depending on {@link RenderStrategy}).
+        * After the listener is invoked the page containing the component will 
be rendered
+        * (with an optional redirect - depending on {@link RenderStrategy}).
         *
         * @param component
-        * @param behavior
+        * @param listener
         */
        public void invokeListener(Component component, final Behavior behavior)
        {
@@ -1149,9 +1156,8 @@ public class BaseWicketTester
 
                // there are two ways to do this. RequestCycle could be forced 
to call the handler
                // directly but constructing and parsing the URL increases the 
chance of triggering bugs
-               IRequestHandler handler = new ListenerRequestHandler(
-                       new PageAndComponentProvider(component.getPage(), 
component),
-                       component.getBehaviorId(behavior));
+               IRequestHandler handler = new ListenerRequestHandler(new 
PageAndComponentProvider(
+                       component.getPage(), component), 
component.getBehaviorId(behavior));
 
                processRequest(handler);
        }
@@ -1182,8 +1188,8 @@ public class BaseWicketTester
                        serializeFormToRequest(form);
 
                        // mark behavior's component as the form submitter,
-                       String name = Form.getRootFormRelativeId(
-                               new PropertyModel<Component>(behavior, 
"component").getObject());
+                       String name = Form.getRootFormRelativeId(new 
PropertyModel<Component>(behavior,
+                               "component").getObject());
                        if 
(!request.getPostParameters().getParameterNames().contains(name))
                        {
                                
request.getPostParameters().setParameterValue(name, "marked");
@@ -1198,10 +1204,9 @@ public class BaseWicketTester
         *
         * @return Origin header
         */
-       protected String createOriginHeader()
-       {
+       protected String createOriginHeader(){
                Url url = RequestCycle.get().getRequest().getUrl();
-               return url.getProtocol() + "://" + url.getHost() + ":" + 
url.getPort();
+               return url.getProtocol() + "://" +url.getHost() + ":" + 
url.getPort();
        }
 
        /**
@@ -1452,8 +1457,7 @@ public class BaseWicketTester
                        }
                        catch (Exception e)
                        {
-                               String errorMessage = "Error while parsing the 
markup for the autogenerated page: " +
-                                       e.getMessage();
+                               String errorMessage = "Error while parsing the 
markup for the autogenerated page: " + e.getMessage();
                                log.error(errorMessage, e);
                                fail(errorMessage);
                        }
@@ -1516,6 +1520,57 @@ public class BaseWicketTester
        }
 
        /**
+        * A page that is used as the automatically created page for
+        * {@link BaseWicketTester#startComponentInPage(Class)} and the other 
variations.
+        * <p>
+        * This page caches the generated markup so that it is available even 
after
+        * {@link Component#detach()} where the {@link Component#markup 
component's markup cache} is
+        * cleared.
+        */
+       public static class StartComponentInPage extends WebPage
+       {
+               private transient IMarkupFragment pageMarkup = null;
+
+               /**
+                * Construct.
+                */
+               public StartComponentInPage()
+               {
+                       setStatelessHint(false);
+               }
+
+               @Override
+               public IMarkupFragment getMarkup()
+               {
+                       IMarkupFragment calculatedMarkup = null;
+                       if (pageMarkup == null)
+                       {
+                               IMarkupFragment markup = super.getMarkup();
+                               if (markup != null && markup != 
Markup.NO_MARKUP)
+                               {
+                                       calculatedMarkup = markup;
+                                       pageMarkup = markup;
+                               }
+                       }
+                       else
+                       {
+                               calculatedMarkup = pageMarkup;
+                       }
+
+                       return calculatedMarkup;
+               }
+
+               /**
+                * @param markup
+                */
+               public void setPageMarkup(IMarkupFragment markup)
+               {
+                       setMarkup(markup);
+                       pageMarkup = markup;
+               }
+       }
+
+       /**
         * Gets the component with the given path from last rendered page. This 
method fails in case the
         * component couldn't be found.
         *
@@ -1600,9 +1655,8 @@ public class BaseWicketTester
        {
                Component component = assertExists(path);
 
-               return isTrue(
-                       "component '" + Classes.name(component.getClass()) + "' 
is not of type: " +
-                               Classes.name(expectedComponentClass),
+               return isTrue("component '" + 
Classes.name(component.getClass()) + "' is not of type: " +
+                       Classes.name(expectedComponentClass),
                        
expectedComponentClass.isAssignableFrom(component.getClass()));
        }
 
@@ -1686,26 +1740,24 @@ public class BaseWicketTester
                return isFalse("component '" + path + "' is enabled", 
component.isEnabledInHierarchy());
        }
 
-       protected Component assertExists(final String path)
-       {
+       protected Component assertExists(final String path) {
                Component component = getComponentFromLastRenderedPage(path);
                if (component == null)
                {
                        fail("path: '" + path + "' does no exist for page: " +
-                               
Classes.simpleName(getLastRenderedPage().getClass()));
+                            
Classes.simpleName(getLastRenderedPage().getClass()));
                }
                return component;
        }
 
-       private FormComponent<?> assertFormComponent(final String path)
-       {
+       private FormComponent assertFormComponent(final String path) {
                Component component = assertExists(path);
 
-               if (component instanceof FormComponent<?> == false)
+               if (component instanceof FormComponent == false)
                {
                        fail("path: '" + path + "' is not a form component");
                }
-               return (FormComponent<?>)component;
+               return (FormComponent) component;
        }
 
        /**
@@ -1717,7 +1769,7 @@ public class BaseWicketTester
         */
        public Result isRequired(String path)
        {
-               FormComponent<?> formComponent = assertFormComponent(path);
+               FormComponent formComponent = assertFormComponent(path);
 
                return isRequired(formComponent);
        }
@@ -1743,7 +1795,7 @@ public class BaseWicketTester
         */
        public Result isNotRequired(String path)
        {
-               FormComponent<?> formComponent = assertFormComponent(path);
+               FormComponent formComponent = assertFormComponent(path);
 
                return isNotRequired(formComponent);
        }
@@ -1860,8 +1912,8 @@ public class BaseWicketTester
                                        "not be invoked when AJAX (javascript) 
is disabled.");
                        }
 
-                       List<AjaxEventBehavior> behaviors = WicketTesterHelper
-                               .findAjaxEventBehaviors(linkComponent, "click");
+                       List<AjaxEventBehavior> behaviors = 
WicketTesterHelper.findAjaxEventBehaviors(
+                               linkComponent, "click");
                        for (AjaxEventBehavior behavior : behaviors)
                        {
                                executeBehavior(behavior);
@@ -1887,11 +1939,10 @@ public class BaseWicketTester
                                
(AjaxFormSubmitBehavior)WicketTesterHelper.findAjaxEventBehavior(link, 
"click"));
                }
                // if the link is an IAjaxLink, use it (do check if AJAX is 
expected)
-               else if (isAjax &&
-                       (linkComponent instanceof IAjaxLink || linkComponent 
instanceof AjaxFallbackLink))
+               else if (isAjax && (linkComponent instanceof IAjaxLink || 
linkComponent instanceof AjaxFallbackLink))
                {
-                       List<AjaxEventBehavior> behaviors = WicketTesterHelper
-                               .findAjaxEventBehaviors(linkComponent, "click");
+                       List<AjaxEventBehavior> behaviors = 
WicketTesterHelper.findAjaxEventBehaviors(
+                               linkComponent, "click");
                        for (AjaxEventBehavior behavior : behaviors)
                        {
                                executeBehavior(behavior);
@@ -1912,7 +1963,7 @@ public class BaseWicketTester
                }
                else if (linkComponent instanceof ExternalLink)
                {
-                       ExternalLink externalLink = (ExternalLink)linkComponent;
+                       ExternalLink externalLink = (ExternalLink) 
linkComponent;
                        String href = 
externalLink.getDefaultModelObjectAsString();
                        try
                        {
@@ -1922,8 +1973,7 @@ public class BaseWicketTester
                        }
                        catch (IOException iox)
                        {
-                               throw new WicketRuntimeException("An error 
occurred while redirecting to: " + href,
-                                       iox);
+                               throw new WicketRuntimeException("An error 
occurred while redirecting to: " + href, iox);
                        }
                }
                // if the link is a normal link (or ResourceLink)
@@ -1940,34 +1990,34 @@ public class BaseWicketTester
                                BookmarkablePageLink<?> bookmarkablePageLink = 
(BookmarkablePageLink<?>)link;
                                try
                                {
-                                       Method getParametersMethod = 
BookmarkablePageLink.class
-                                               
.getDeclaredMethod("getPageParameters", (Class<?>[])null);
+                                       Method getParametersMethod = 
BookmarkablePageLink.class.getDeclaredMethod(
+                                               "getPageParameters", 
(Class<?>[])null);
                                        getParametersMethod.setAccessible(true);
 
-                                       PageParameters parameters = 
(PageParameters)getParametersMethod
-                                               .invoke(bookmarkablePageLink, 
(Object[])null);
+                                       PageParameters parameters = 
(PageParameters)getParametersMethod.invoke(
+                                               bookmarkablePageLink, 
(Object[])null);
 
                                        
startPage(bookmarkablePageLink.getPageClass(), parameters);
                                }
                                catch (Exception e)
                                {
-                                       throw new 
WicketRuntimeException("Internal error in WicketTester. " +
-                                               "Please report this in Wicket's 
Issue Tracker.", e);
+                                       throw new 
WicketRuntimeException("Internal error in WicketTester. "
+                                               + "Please report this in 
Wicket's Issue Tracker.", e);
                                }
                        }
                        else if (link instanceof ResourceLink)
                        {
                                try
                                {
-                                       Method getURL = 
ResourceLink.class.getDeclaredMethod("getURL");
+                                       Method getURL = 
ResourceLink.class.getDeclaredMethod("getURL", new Class[0]);
                                        getURL.setAccessible(true);
                                        CharSequence url = 
(CharSequence)getURL.invoke(link);
                                        executeUrl(url.toString());
                                }
                                catch (Exception x)
                                {
-                                       throw new RuntimeException("An error 
occurred while clicking on a ResourceLink",
-                                               x);
+                                       throw new RuntimeException(
+                                               "An error occurred while 
clicking on a ResourceLink", x);
                                }
                        }
                        else
@@ -2011,8 +2061,10 @@ public class BaseWicketTester
        public void submitForm(String path)
        {
                Form<?> form = (Form<?>)getComponentFromLastRenderedPage(path);
-               Url url = Url.parse(form.getRootForm().urlForListener(new 
PageParameters()).toString(),
-                       Charset.forName(request.getCharacterEncoding()));
+               Url url = Url.parse(
+                       form.getRootForm()
+                               .urlForListener(new PageParameters())
+                               .toString(), 
Charset.forName(request.getCharacterEncoding()));
 
                // make url absolute
                transform(url);
@@ -2090,8 +2142,10 @@ public class BaseWicketTester
         * @param expectedDocument
         *            expected output
         * @return a <code>Result</code>
-     */
-       public Result isResultPage(final String expectedDocument) {
+        * @throws Exception
+        */
+       public Result isResultPage(final String expectedDocument) throws 
Exception
+       {
                // Validate the document
                String document = getLastResponseAsString();
                return isTrue("expected rendered page equals", 
document.equals(expectedDocument));
@@ -2123,15 +2177,16 @@ public class BaseWicketTester
         * Asserts there are no feedback messages with the given level.
         *
         * @param level
-        *            the level of the feedback message
+        *              the level of the feedback message
         * @return a <code>Result</code>
         */
        public Result hasNoFeedbackMessage(int level)
        {
                List<Serializable> messages = getMessages(level);
-               return isTrue(String.format("expected no %s message, but 
contains\n%s",
-                       new FeedbackMessage(null, "", 
level).getLevelAsString().toLowerCase(Locale.ENGLISH),
-                       WicketTesterHelper.asLined(messages)), 
messages.isEmpty());
+               return isTrue(
+                               String.format("expected no %s message, but 
contains\n%s",
+                                               new FeedbackMessage(null, "", 
level).getLevelAsString().toLowerCase(Locale.ENGLISH), 
WicketTesterHelper.asLined(messages)),
+                               messages.isEmpty());
        }
 
        /**
@@ -2145,8 +2200,7 @@ public class BaseWicketTester
         */
        public List<Serializable> getMessages(final int level)
        {
-               List<FeedbackMessage> messages = getFeedbackMessages(
-                       new ExactLevelFeedbackMessageFilter(level));
+               List<FeedbackMessage> messages = getFeedbackMessages(new 
ExactLevelFeedbackMessageFilter(level));
 
                List<Serializable> actualMessages = Generics.newArrayList();
                for (FeedbackMessage message : messages)
@@ -2195,13 +2249,11 @@ public class BaseWicketTester
        public void debugComponentTrees(String filter)
        {
                log.info("debugging 
----------------------------------------------");
-               for (WicketTesterHelper.ComponentData obj : WicketTesterHelper
-                       .getComponentData(getLastRenderedPage()))
+               for (WicketTesterHelper.ComponentData obj : 
WicketTesterHelper.getComponentData(getLastRenderedPage()))
                {
                        if (obj.path.matches(".*" + filter + ".*"))
                        {
-                               log.info("[{}{}] path\t" + obj.path + " \t" + 
obj.type + " \t[" + obj.value + "]",
-                                       obj.isEnabled ? "E" : "-", 
obj.isVisible ? "V" : "-");
+                               log.info("[{}{}] path\t" + obj.path + " \t" + 
obj.type + " \t[" + obj.value + "]", obj.isEnabled?"E":"-", 
obj.isVisible?"V":"-");
                        }
                }
        }
@@ -2231,9 +2283,9 @@ public class BaseWicketTester
                String componentInfo = component.toString();
                if (!component.isVisible())
                {
-                       failMessage = "A component which is invisible and 
doesn't render a placeholder tag" +
-                               " will not be rendered at all and thus won't be 
accessible for subsequent AJAX interaction. " +
-                               componentInfo;
+                       failMessage = "A component which is invisible and 
doesn't render a placeholder tag"
+                               + " will not be rendered at all and thus won't 
be accessible for subsequent AJAX interaction. " +
+                                       componentInfo;
                        result = isTrue(failMessage, 
component.getOutputMarkupPlaceholderTag());
                        if (result.wasFailed())
                        {
@@ -2245,11 +2297,11 @@ public class BaseWicketTester
                String ajaxResponse = getLastResponseAsString();
 
                // Test that the previous response was actually a AJAX response
-               failMessage = "The previous response was not an AJAX response. 
" +
-                       "You need to execute an AJAX event, using #clickLink() 
or " +
-                       "#executeAjaxEvent(), before using this assertion 
method";
-               boolean isAjaxResponse = Pattern
-                       .compile("^<\\?xml version=\"1.0\" 
encoding=\".*?\"\\?><ajax-response>")
+               failMessage = "The previous response was not an AJAX response. 
"+
+                               "You need to execute an AJAX event, using 
#clickLink() or " +
+                               "#executeAjaxEvent(), before using this 
assertion method";
+               boolean isAjaxResponse = Pattern.compile(
+                       "^<\\?xml version=\"1.0\" 
encoding=\".*?\"\\?><ajax-response>")
                        .matcher(ajaxResponse)
                        .find();
                result = isTrue(failMessage, isAjaxResponse);
@@ -2262,7 +2314,8 @@ public class BaseWicketTester
                String markupId = component.getMarkupId();
 
                failMessage = "The component doesn't have a markup id, " +
-                       "which means that it can't have been added to the AJAX 
response. " + componentInfo;
+                               "which means that it can't have been added to 
the AJAX response. " +
+                               componentInfo;
                result = isTrue(failMessage, !Strings.isEmpty(markupId));
                if (result.wasFailed())
                {
@@ -2270,27 +2323,23 @@ public class BaseWicketTester
                }
 
                // Look for that the component is on the response, using the 
markup id
-               boolean isComponentInAjaxResponse = ajaxResponse
-                       .matches("(?s).*<component id=\"" + markupId + 
"\"[^>]*?>.*");
+               boolean isComponentInAjaxResponse = 
ajaxResponse.matches("(?s).*<component id=\"" +
+                       markupId + "\"[^>]*?>.*");
                failMessage = "Component wasn't found in the AJAX response. " + 
componentInfo;
                result = isTrue(failMessage, isComponentInAjaxResponse);
 
-               if (!result.wasFailed())
-               {
+               if (!result.wasFailed()) {
                        return result;
                }
 
                // Check if the component has been included as part of an 
enclosure render
-               Enclosure enclosure = 
getLastRenderedPage().visitChildren(Enclosure.class,
-                       (Enclosure enc, IVisit<Enclosure> visit) -> {
-                               if 
(AjaxEnclosureListener.isControllerOfEnclosure(component, enc))
-                               {
-                                       visit.stop(enc);
-                               }
-                       });
+               Enclosure enclosure = 
getLastRenderedPage().visitChildren(Enclosure.class, (Enclosure enc, 
IVisit<Enclosure> visit) -> {
+                       if 
(AjaxEnclosureListener.isControllerOfEnclosure(component, enc)){
+                               visit.stop(enc);
+                       }
+               });
 
-               if (enclosure == null)
-               {
+               if (enclosure == null) {
                        return result;
                }
 
@@ -2342,8 +2391,7 @@ public class BaseWicketTester
 
        private void internalExecuteAllTimerBehaviors(final Component component)
        {
-               List<AbstractAjaxTimerBehavior> behaviors = component
-                       .getBehaviors(AbstractAjaxTimerBehavior.class);
+               List<AbstractAjaxTimerBehavior> behaviors = 
component.getBehaviors(AbstractAjaxTimerBehavior.class);
                for (AbstractAjaxTimerBehavior timer : behaviors)
                {
                        checkUsability(component, true);
@@ -2403,8 +2451,8 @@ public class BaseWicketTester
 
                checkUsability(component, true);
 
-               List<AjaxEventBehavior> ajaxEventBehaviors = WicketTesterHelper
-                       .findAjaxEventBehaviors(component, event);
+               List<AjaxEventBehavior> ajaxEventBehaviors = 
WicketTesterHelper.findAjaxEventBehaviors(
+                       component, event);
                for (AjaxEventBehavior ajaxEventBehavior : ajaxEventBehaviors)
                {
                        executeBehavior(ajaxEventBehavior);
@@ -2652,21 +2700,19 @@ public class BaseWicketTester
 
                if (component.isVisibleInHierarchy() == false)
                {
-                       res = Result.fail(
-                               "The component is currently not visible in the 
hierarchy and thus you can not be used." +
-                                       " Component: " + component);
+                       res = Result.fail("The component is currently not 
visible in the hierarchy and thus you can not be used." +
+                               " Component: " + component);
                }
 
                if (component.isEnabledInHierarchy() == false)
                {
-                       res = Result.fail(
-                               "The component is currently not enabled in the 
hierarchy and thus you can not be used." +
-                                       " Component: " + component);
+                       res = Result.fail("The component is currently not 
enabled in the hierarchy and thus you can not be used." +
+                               " Component: " + component);
                }
 
                if (throwException && res.wasFailed())
                {
-                       throw new AssertionError(res.getMessage());
+                       throw new AssertionFailedError(res.getMessage());
                }
                return res;
        }
@@ -2742,109 +2788,6 @@ public class BaseWicketTester
                processRequest();
        }
 
-       /**
-        * A page that is used as the automatically created page for
-        * {@link BaseWicketTester#startComponentInPage(Class)} and the other 
variations.
-        * <p>
-        * This page caches the generated markup so that it is available even 
after
-        * {@link Component#detach()} where the {@link Component#markup 
component's markup cache} is
-        * cleared.
-        */
-       public static class StartComponentInPage extends WebPage
-       {
-               private transient IMarkupFragment pageMarkup = null;
-
-               /**
-                * Construct.
-                */
-               public StartComponentInPage()
-               {
-                       setStatelessHint(false);
-               }
-
-               @Override
-               public IMarkupFragment getMarkup()
-               {
-                       IMarkupFragment calculatedMarkup = null;
-                       if (pageMarkup == null)
-                       {
-                               IMarkupFragment markup = super.getMarkup();
-                               if (markup != null && markup != 
Markup.NO_MARKUP)
-                               {
-                                       calculatedMarkup = markup;
-                                       pageMarkup = markup;
-                               }
-                       }
-                       else
-                       {
-                               calculatedMarkup = pageMarkup;
-                       }
-
-                       return calculatedMarkup;
-               }
-
-               /**
-                * @param markup
-                */
-               public void setPageMarkup(IMarkupFragment markup)
-               {
-                       setMarkup(markup);
-                       pageMarkup = markup;
-               }
-       }
-
-       private static class TestPageManagerProvider implements 
IPageManagerProvider
-       {
-               @Override
-               public IPageManager apply(IPageManagerContext 
pageManagerContext)
-               {
-                       return new MockPageManager();
-               }
-       }
-
-       private static class WicketTesterServletWebResponse extends 
ServletWebResponse
-               implements
-                       IMetaDataBufferingWebResponse
-       {
-               private List<Cookie> cookies = new ArrayList<Cookie>();
-
-               private WicketTesterServletWebResponse(ServletWebRequest 
request,
-                       MockHttpServletResponse response)
-               {
-                       super(request, response);
-               }
-
-               @Override
-               public void addCookie(Cookie cookie)
-               {
-                       super.addCookie(cookie);
-                       cookies.add(cookie);
-               }
-
-               @Override
-               public void writeMetaData(WebResponse webResponse)
-               {
-                       for (Cookie cookie : cookies)
-                       {
-                               webResponse.addCookie(cookie);
-                       }
-               }
-
-               @Override
-               public void sendRedirect(String url)
-               {
-                       super.sendRedirect(url);
-                       try
-                       {
-                               getContainerResponse().sendRedirect(url);
-                       }
-                       catch (IOException e)
-                       {
-                               throw new RuntimeException(e);
-                       }
-               }
-       }
-
        private class LastPageRecordingPageRendererProvider implements 
IPageRendererProvider
        {
                private final IPageRendererProvider delegate;
@@ -2870,8 +2813,8 @@ public class BaseWicketTester
                                        if 
(handler.getPageProvider().hasPageInstance())
                                        {
                                                Page renderedPage = 
(Page)handler.getPageProvider().getPageInstance();
-                                               if (componentInPage != null && 
lastPage != null && renderedPage != null &&
-                                                       lastPage.getPageClass() 
!= renderedPage.getPageClass())
+                                               if (componentInPage != null && 
lastPage != null && renderedPage != null
+                                                       && 
lastPage.getPageClass() != renderedPage.getPageClass())
                                                {
                                                        // WICKET-3913: reset 
startComponent if a new page
                                                        // type is rendered
@@ -2980,6 +2923,15 @@ public class BaseWicketTester
                }
        }
 
+       private static class TestPageManagerProvider implements 
IPageManagerProvider
+       {
+               @Override
+               public IPageManager get()
+               {
+                       return new PageManager(new MockPageStore());
+               }
+       }
+
        public class TestFilterConfig implements FilterConfig
        {
                private final Map<String, String> initParameters = new 
HashMap<String, String>();
@@ -3013,4 +2965,47 @@ public class BaseWicketTester
                        throw new UnsupportedOperationException("Not 
implemented");
                }
        }
+
+       private static class WicketTesterServletWebResponse extends 
ServletWebResponse
+               implements
+                       IMetaDataBufferingWebResponse
+       {
+               private List<Cookie> cookies = new ArrayList<Cookie>();
+
+               private WicketTesterServletWebResponse(ServletWebRequest 
request,
+                                                      MockHttpServletResponse 
response)
+               {
+                       super(request, response);
+               }
+
+               @Override
+               public void addCookie(Cookie cookie)
+               {
+                       super.addCookie(cookie);
+                       cookies.add(cookie);
+               }
+
+               @Override
+               public void writeMetaData(WebResponse webResponse)
+               {
+                       for (Cookie cookie : cookies)
+                       {
+                               webResponse.addCookie(cookie);
+                       }
+               }
+
+               @Override
+               public void sendRedirect(String url)
+               {
+                       super.sendRedirect(url);
+                       try
+                       {
+                               getContainerResponse().sendRedirect(url);
+                       }
+                       catch (IOException e)
+                       {
+                               throw new RuntimeException(e);
+                       }
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/c43d3a33/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/TestMapperContext.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/TestMapperContext.java
 
b/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/TestMapperContext.java
index 2fff6cc..9f1c44d 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/TestMapperContext.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/TestMapperContext.java
@@ -20,19 +20,20 @@ import org.apache.wicket.MockPage;
 import org.apache.wicket.WicketRuntimeException;
 import org.apache.wicket.core.request.handler.PageProvider;
 import org.apache.wicket.markup.MarkupParser;
-import org.apache.wicket.page.IPageManagerContext;
-import org.apache.wicket.page.PageStoreManager;
-import org.apache.wicket.pageStore.DefaultPageStore;
-import org.apache.wicket.pageStore.IDataStore;
-import org.apache.wicket.pageStore.IPageStore;
-import org.apache.wicket.pageStore.memory.DummyPageManagerContext;
+import org.apache.wicket.mock.MockPageStore;
+import org.apache.wicket.page.IPageManager;
+import org.apache.wicket.page.PageManager;
+import org.apache.wicket.pageStore.DummyPageContext;
+import org.apache.wicket.pageStore.IPageContext;
+import org.apache.wicket.pageStore.InMemoryPageStore;
+import org.apache.wicket.pageStore.RequestPageStore;
+import org.apache.wicket.pageStore.InSessionPageStore;
 import org.apache.wicket.request.component.IRequestablePage;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.request.resource.ResourceReference;
 import org.apache.wicket.request.resource.ResourceReference.Key;
 import org.apache.wicket.request.resource.ResourceReferenceRegistry;
 import org.apache.wicket.serialize.java.JavaSerializer;
-import org.apache.wicket.versioning.InMemoryPageStore;
 
 /**
  * Simple {@link IMapperContext} implementation for testing purposes
@@ -43,10 +44,10 @@ public class TestMapperContext implements IMapperContext
 {
        private static final String APP_NAME = "test_app";
        private static int count;
-       private IDataStore dataStore;
-       private IPageStore pageStore;
-       private IPageManagerContext pageManagerContext;
-       private PageStoreManager pageManager;
+
+       InSessionPageStore pageStore;
+       DummyPageContext pageContext;
+       IPageManager pageManager;
        private String appName;
        private boolean createMockPageIfInstanceNotFound = true;
 
@@ -56,10 +57,18 @@ public class TestMapperContext implements IMapperContext
        public TestMapperContext()
        {
                appName = APP_NAME + count++;
-               dataStore = new InMemoryPageStore();
-               pageStore = new DefaultPageStore(new JavaSerializer(appName), 
dataStore, 4);
-               pageManagerContext = new DummyPageManagerContext();
-               pageManager = new PageStoreManager(appName, pageStore, 
pageManagerContext);
+               
+               pageContext = new DummyPageContext();
+               
+               InMemoryPageStore inMemoryPageStore = new 
InMemoryPageStore(appName, Integer.MAX_VALUE);
+               pageStore = new InSessionPageStore(inMemoryPageStore, 4, new 
JavaSerializer(appName));
+               pageManager = new PageManager(new RequestPageStore(pageStore)) {
+                       @Override
+                       protected IPageContext createPageContext()
+                       {
+                               return pageContext;
+                       }
+               };
        }
 
        /**
@@ -67,17 +76,17 @@ public class TestMapperContext implements IMapperContext
         */
        public void cleanSessionCache()
        {
-               getPageManager().getContext().setRequestData(null);
+               pageContext.clearRequest();
                MockPage other = new MockPage();
                other.setPageId(Integer.MAX_VALUE);
-               getPageManager().touchPage(other);
-               getPageManager().commitRequest();
+               getPageManager().addPage(other);
+               pageManager.detach();
        }
 
        /**
         * @return pageManager
         */
-       public PageStoreManager getPageManager()
+       public IPageManager getPageManager()
        {
                return pageManager;
        }
@@ -175,7 +184,7 @@ public class TestMapperContext implements IMapperContext
 
        }
 
-       private int idCounter = 0;
+       int idCounter = 0;
 
        @Override
        public IRequestablePage newPageInstance(Class<? extends 
IRequestablePage> pageClass,
@@ -184,7 +193,7 @@ public class TestMapperContext implements IMapperContext
                try
                {
                        MockPage page;
-                       page = 
(MockPage)pageClass.getDeclaredConstructor().newInstance();
+                       page = (MockPage)pageClass.newInstance();
                        page.setPageId(++idCounter);
                        page.setBookmarkable(true);
                        page.setCreatedBookmarkable(true);

http://git-wip-us.apache.org/repos/asf/wicket/blob/c43d3a33/wicket-core/src/test/java/org/apache/wicket/dontstoreunrendered/DontStoreNotRenderedPageTestCase.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/dontstoreunrendered/DontStoreNotRenderedPageTestCase.java
 
b/wicket-core/src/test/java/org/apache/wicket/dontstoreunrendered/DontStoreNotRenderedPageTestCase.java
index ceac5e3..857c715 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/dontstoreunrendered/DontStoreNotRenderedPageTestCase.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/dontstoreunrendered/DontStoreNotRenderedPageTestCase.java
@@ -24,8 +24,6 @@ import 
org.apache.wicket.application.IComponentInstantiationListener;
 import org.apache.wicket.behavior.Behavior;
 import org.apache.wicket.mock.MockPageManager;
 import org.apache.wicket.page.IManageablePage;
-import org.apache.wicket.page.IPageManager;
-import org.apache.wicket.page.IPageManagerContext;
 import org.apache.wicket.protocol.http.WebApplication;
 import org.apache.wicket.util.tester.WicketTestCase;
 import org.apache.wicket.util.tester.WicketTester;
@@ -34,7 +32,7 @@ import org.junit.jupiter.api.Test;
 /**
  * https://issues.apache.org/jira/browse/WICKET-5415
  */
-abstract class DontStoreNotRenderedPageTestCase extends WicketTestCase
+public abstract class DontStoreNotRenderedPageTestCase extends WicketTestCase
 {
        @Override
        protected WicketTester newWicketTester(WebApplication app)
@@ -56,30 +54,27 @@ abstract class DontStoreNotRenderedPageTestCase extends 
WicketTestCase
                        @Override
                        protected IPageManagerProvider 
newTestPageManagerProvider()
                        {
-                               return new IPageManagerProvider()
-                               {
-                                       @Override
-                                       public IPageManager 
apply(IPageManagerContext context)
+                               return () -> {
+                                       return new MockPageManager()
                                        {
-                                               return new MockPageManager()
+                                               @Override
+                                               public void 
addPage(IManageablePage page)
                                                {
-                                                       @Override
-                                                       public void 
touchPage(IManageablePage page)
-                                                       {
-                                                               
assertFalse(page instanceof PageB, "PageB should not be touched!");
-                                                               
super.touchPage(page);
-                                                       }
-                                               };
-                                       }
+                                                       assertFalse(page 
instanceof PageB, "PageB should not be touched!");
+                                                       super.addPage(page);
+                                               }
+                                       };
                                };
                        }
                };
        }
 
        /**
-        * Start with PageA. Then click a link to go to PageB. PageB throws a
-        * RestartResponseException(PageC) in its constructor, so it shouldn't 
be neither initialized
-        * nor rendered. PageC is rendered.
+        * Start with PageA.
+        * Then click a link to go to PageB.
+        * PageB throws a RestartResponseException(PageC) in its constructor, so
+        * it shouldn't be neither initialized nor rendered.
+        * PageC is rendered.
         *
         * Verifies that PageB is not initialized, rendered and stored by 
PageManager
         */

http://git-wip-us.apache.org/repos/asf/wicket/blob/c43d3a33/wicket-core/src/test/java/org/apache/wicket/markup/html/TransparentWebMarkupContainerTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/TransparentWebMarkupContainerTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/TransparentWebMarkupContainerTest.java
index da853e4..39d81c3 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/TransparentWebMarkupContainerTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/TransparentWebMarkupContainerTest.java
@@ -38,7 +38,7 @@ import org.apache.wicket.markup.html.panel.Fragment;
 import org.apache.wicket.mock.MockPageManager;
 import org.apache.wicket.page.IManageablePage;
 import org.apache.wicket.page.IPageManager;
-import org.apache.wicket.page.IPageManagerContext;
+import org.apache.wicket.pageStore.IPageContext;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.util.resource.IResourceStream;
 import org.apache.wicket.util.resource.StringResourceStream;
@@ -120,15 +120,15 @@ public class TransparentWebMarkupContainerTest extends 
WicketTestCase
                                return new IPageManagerProvider()
                                {
                                        @Override
-                                       public IPageManager 
apply(IPageManagerContext context)
+                                       public IPageManager get()
                                        {
                                                return new MockPageManager()
                                                {
                                                        @Override
-                                                       public void 
touchPage(IManageablePage page)
+                                                       public void 
addPage(IManageablePage page)
                                                        {
                                                                page = 
WicketObjects.cloneObject(page);
-                                                               
super.touchPage(page);
+                                                               
super.addPage(page);
                                                        }
                                                };
                                        }

http://git-wip-us.apache.org/repos/asf/wicket/blob/c43d3a33/wicket-core/src/test/java/org/apache/wicket/page/PageAccessSynchronizerTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/page/PageAccessSynchronizerTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/page/PageAccessSynchronizerTest.java
index c686d6a..ad697ed 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/page/PageAccessSynchronizerTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/page/PageAccessSynchronizerTest.java
@@ -323,7 +323,7 @@ class PageAccessSynchronizerTest
 
                int pageId = 1;
                IManageablePage page = new MockPage(pageId);
-               synchronizedPageManager.touchPage(page);
+               synchronizedPageManager.addPage(page);
                synchronizedPageManager.getPage(pageId);
                PageLock pageLock2 = locks.get(Integer.valueOf(pageId));
                assertNotNull(pageLock2);

Reply via email to