/** https://issues.apache.org/jira/browse/WICKET-4009 */
  @Test
  public void unlockIfNoSuchPage() {
    PageAccessSynchronizer synchronizer = new PageAccessSynchronizer(Duration.seconds(2));
    IPageManager pageManager = new MockPageManager();
    IPageManager synchronizedPageManager = synchronizer.adapt(pageManager);
    synchronizedPageManager.getPage(0);
    ConcurrentMap<Integer, PageLock> locks = synchronizer.getLocks().get();
    PageLock pageLock = locks.get(Integer.valueOf(0));
    assertNull(pageLock);

    int pageId = 1;
    IManageablePage page = new MockPage(pageId);
    synchronizedPageManager.touchPage(page);
    synchronizedPageManager.getPage(pageId);
    PageLock pageLock2 = locks.get(Integer.valueOf(pageId));
    assertNotNull(pageLock2);
  }
  /**
   * WICKET-3470
   *
   * <p>Tests that a page already put in the session (in SessionEntry) can be serialized and later
   * deserialized without the need of {@link IPageStore}
   *
   * @throws ClassNotFoundException
   * @throws IOException
   */
  @Test
  public void serializationOutsideWicketLifecyle() throws IOException, ClassNotFoundException {
    // make sure no leaked threadlocals are present
    ThreadContext.detach();

    // create IPageManager (with IPageStore) and store a page instance
    IPageManager pageManager = newPersistentPageManager(APP_NAME);
    TestPage toSerializePage = new TestPage();
    pageManager.touchPage(toSerializePage);
    pageManager.commitRequest();

    // get the stored SessionEntry
    Serializable sessionEntry = pageManager.getContext().getSessionAttribute(null);

    // destroy the manager and the store
    pageManager.destroy();

    // simulate persisting of the http sessions initiated by the web container
    byte[] serializedSessionEntry = new JavaSerializer(APP_NAME).serialize(sessionEntry);
    assertNotNull("Wicket needs to be able to serialize the session entry", serializedSessionEntry);

    // simulate loading of the persisted http session initiated by the web container
    // when starting an application
    ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(serializedSessionEntry));

    // WicketFilter is not initialized so there is no Application available yet
    Assert.assertFalse(
        "Worker thread should be unaware of Wicket application", Application.exists());

    assertEquals(APP_NAME, in.readObject());

    // without available IPageStore the read SessionEntry holds
    // the IManageablePage itself, not SerializedPage
    Serializable loadedSessionEntry = (Serializable) in.readObject();
    assertNotNull(
        "Wicket needs to be able to deserialize the session entry regardless the application availability",
        loadedSessionEntry);

    // provide new IPageStore which will read IManageablePage's or SerializedPage's
    // from the SessionEntry's
    IPageManager newPageManager = newPersistentPageManager(APP_NAME);
    newPageManager.getContext().setSessionAttribute(null, loadedSessionEntry);

    TestPage deserializedPage = (TestPage) newPageManager.getPage(toSerializePage.getPageId());
    assertNotNull(deserializedPage);
    assertEquals(toSerializePage.instanceID, deserializedPage.instanceID);

    newPageManager.destroy();
  }