/** @return the identifier for the page form */
 protected String registerPageForm(IPage p, IForm f) {
   String id = createUniqueIdForPage(p, f);
   m_formToIdentifierMap.put(f, id);
   f.removeFormListener(m_formListener);
   f.addFormListener(m_formListener);
   return id;
 }
 @Override
 public void pageSearchFormStarted(IPageWithTable<?> p) throws ProcessingException {
   if (p.getOutline() instanceof AbstractPageField.SimpleOutline) {
     return;
   }
   IForm f = p.getSearchFormInternal();
   if (f != null) {
     String pageFormIdentifier = registerPageForm(p, f);
     if (f.isFormOpen()) {
       loadSearchFormState(f, pageFormIdentifier);
     }
   }
 }
  /**
   * Since this property depends on the user agent it is saved separately for each combination of
   * {@link org.eclipse.scout.rt.shared.ui.IUiLayer IUiLayer} and {@link
   * org.eclipse.scout.rt.shared.ui.IUiDeviceType IUiDeviceType}.
   */
  public Rectangle getFormBounds(IForm form) {
    String key = form.computeCacheBoundsKey();
    if (key == null) {
      return null;
    }

    key = getUserAgentPrefix() + FORM_BOUNDS + key;
    String value = m_env.get(key, "");
    if (StringUtility.isNullOrEmpty(value)) {
      key = getLegacyFormBoundsKey(form);
      value = m_env.get(key, "");
    }

    if (!StringUtility.isNullOrEmpty(value)) {
      try {
        StringTokenizer tok = new StringTokenizer(value, ",");
        Rectangle r =
            new Rectangle(
                new Integer(tok.nextToken()).intValue(),
                new Integer(tok.nextToken()).intValue(),
                new Integer(tok.nextToken()).intValue(),
                new Integer(tok.nextToken()).intValue());
        return r;
      } catch (Exception e) {
        LOG.warn("value=" + value, e);
      }
    }
    return null;
  }
  /**
   * Since this property depends on the user agent it is saved separately for each combination of
   * {@link org.eclipse.scout.rt.shared.ui.IUiLayer IUiLayer} and {@link
   * org.eclipse.scout.rt.shared.ui.IUiDeviceType IUiDeviceType}.
   */
  public void setFormBounds(IForm form, Rectangle bounds) {
    String key = form.computeCacheBoundsKey();
    if (key == null) {
      return;
    }

    key = getUserAgentPrefix() + FORM_BOUNDS + key;
    if (bounds == null) {
      m_env.remove(key);
    } else {
      m_env.put(key, bounds.x + "," + bounds.y + "," + bounds.width + "," + bounds.height);
    }
    flush();
  }
  private String getLegacyFormBoundsKey(IForm form) {
    String key = form.computeCacheBoundsKey();
    if (key == null) {
      return null;
    }

    // Add prefix only if not already added.
    // This is mainly necessary due to backward compatibility because until 3.8.0 the prefix had to
    // be returned by computeCacheBoundsKey
    if (!key.startsWith("form.bounds")) {
      key = "form.bounds_" + key;
    }

    // Explicitly don't consider user agent because before 3.8.0 there was no user agent and
    // therefore the keys didn't contain this information.

    return key;
  }