@SuppressWarnings("unchecked")
  public <T> T get(Class<T> asoClass, ApplicationStateCreator<T> creator) {
    Session session = getSession();

    String key = buildKey(asoClass);

    Map<String, Object> asoMap = getASOMap();

    T aso = (T) asoMap.get(key);

    if (aso != null) return aso;

    // Otherwise, get/create it in the session and record it in the
    // aso map.

    aso = (T) session.getAttribute(key);

    if (aso == null) {
      aso = creator.create();
      session.setAttribute(key, aso);
    }

    asoMap.put(key, aso);

    return aso;
  }
 @Override
 public void exitCurrentScreen() {
   Session session = request.getSession(false);
   if (session != null) {
     LOG.trace("Clearing current screen.");
     session.setAttribute(SESSION_KEY, null);
   }
 }
 @Override
 public void setupOrRestoreScreen(String screenName) {
   Session session = request.getSession(true);
   ScreenState screen = (ScreenState) session.getAttribute(SESSION_KEY);
   if (screen == null || !screen.getName().equals(screenName)) {
     LOG.trace("Creating new screen state with name " + screenName);
     session.setAttribute(SESSION_KEY, new ScreenState(screenName));
   }
 }
  public void requestDidComplete() {
    Map<String, Object> map = getASOMap();

    for (String key : map.keySet()) {
      Object aso = map.get(key);

      if (aso == null) continue;

      if (needsRestore(aso)) {
        Session session = request.getSession(true);

        // It is expected that the ASO implements HttpSessionBindingListener and
        // can clear its dirty flag as it is saved.

        session.setAttribute(key, aso);
      }
    }
  }
  public void setClientTimeZone(TimeZone timeZone) {
    assert timeZone != null;

    identified = true;

    if (timeZone == this.timeZone) return;

    this.timeZone = timeZone;

    cookies.writeCookieValue(COOKIE_NAME, timeZone.getID());

    // Write to the Session, if it exists, in case the client doesn't support cookies.

    Session session = request.getSession(false);

    if (session != null) session.setAttribute(ATTRIBUTE_NAME, timeZone.getID());

    // Worst case: no session yet AND client doesn't support cookies. That means we'll likely
    // keep tracking the time zone (on the client) and updating (here on the server) until
    // a session gets created.
  }