throws Throwable
  public static boolean session_start(Env env)    throws Throwable  {    if (env.getSession() != null) {      env.notice(L.l("session has already been started"));      return true;    }    SessionCallback callback = env.getSessionCallback();    Value sessionIdValue = (Value) env.getSpecialValue("caucho.session_id");    String sessionId = null;    final HttpServletResponse response = env.getResponse();    env.removeConstant("SID");    String cookieName = env.getIni("session.name").toString();    if (callback != null)      callback.open(env, WorkDir.getLocalWorkDir().getPath(), cookieName);    boolean generateCookie = true;    if (sessionIdValue != null)      sessionId = sessionIdValue.toString();    if (sessionId == null || "".equals(sessionId)) {      Cookie []cookies = env.getRequest().getCookies();      for (int i = 0; cookies != null && i < cookies.length; i++) {        if (cookies[i].getName().equals(cookieName)) {          sessionId = cookies[i].getValue();          generateCookie = false;        }      }    }    if (! generateCookie) {      env.addConstant("SID", StringValue.EMPTY, false);    }    else {      if (sessionId == null || "".equals(sessionId))        sessionId = generateSessionId(env);      env.addConstant("SID", new StringValueImpl(cookieName + '=' + sessionId), false);      Cookie cookie = new Cookie(cookieName, sessionId);      cookie.setVersion(1);      if (response.isCommitted()) {        env.warning(L.l("cannot send session cookie because response is committed"));      }      else {        Value path = env.getIni("session.cookie_path");        cookie.setPath(path.toString());        Value maxAge = env.getIni("session.cookie_lifetime");        if (maxAge.toInt() != 0)          cookie.setMaxAge(maxAge.toInt());        Value domain = env.getIni("session.cookie_domain");        cookie.setDomain(domain.toString());        Value secure = env.getIni("session.cookie_secure");        cookie.setSecure(secure.toBoolean());        response.addCookie(cookie);      }    }    env.setSpecialValue("caucho.session_id", new StringValueImpl(sessionId));    if (response.isCommitted())      env.warning(L.l("cannot send session cache limiter headers because response is committed"));    else {      Value cacheLimiterValue = env.getIni("session.cache_limiter");      String cacheLimiter = String.valueOf(cacheLimiterValue);      Value cacheExpireValue = env.getIni("session.cache_expire");      int cacheExpire = cacheExpireValue.toInt() * 60;      if ("nocache".equals(cacheLimiter)) {        response.setHeader("Expires", "Thu, 19 Nov 1981 08:52:00 GMT");        response.addHeader("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0");        response.addHeader("Pragma", "no-cache");      }      else if ("private".equals(cacheLimiter)) {        response.setHeader("Expires", "Thu, 19 Nov 1981 08:52:00 GMT");        response.addHeader("Cache-Control", "private, max-age=" + cacheExpire + ", pre-check=" + cacheExpire);        response.setDateHeader("Last-Modified", env.getLastModified());      }      else if ("private_no_expire".equals(cacheLimiter)) {        response.addHeader("Cache-Control", "private, max-age=" + cacheExpire + ", pre-check=" + cacheExpire);        response.setDateHeader("Last-Modified", env.getLastModified());      }      else if ("public".equals(cacheLimiter)) {        response.setDateHeader("Expires", Alarm.getCurrentTime());        response.addHeader("Cache-Control", "public, max-age=" + cacheExpire);        response.setDateHeader("Last-Modified", env.getLastModified());      }    }    env.createSession(sessionId);    return true;  }