/*------------------------------------------------------------ */
  @Override
  public void doStart() throws Exception {
    super.doStart();
    __log.debug("KVStoreSessionManager::doStart method");
    String kvstorename = this._session_id_manager.getKvstorename();
    if (kvstorename == null) throw new IllegalStateException("kvstore name is null");
    String kvstorehosts = this._session_id_manager.getKvstorehosts();
    if (kvstorehosts == null) throw new IllegalStateException("kvstore hosts list is null");
    this._kvstorehandler = this._session_id_manager.getKVStore();
    String[] hhosts = this._session_id_manager.getKvstorehosts().split(",");
    KVStoreConfig kconfig = new KVStoreConfig(this._session_id_manager.getKvstorename(), hhosts);
    KVStore kvstore = KVStoreFactory.getStore(kconfig);
    if (kvstore == null)
      throw new IllegalStateException(
          "cannot connect to kvstore, hosts=" + kvstorehosts + ";storename=" + kvstorename);
    else __log.debug("succesfully connected to the kvstore instance");
    this._kvstorehandler = kvstore;

    if (this._kvstorehandler == null)
      throw new IllegalStateException("kvstore handler passed from session id manager is null");
    String[] hosts = getContextHandler().getVirtualHosts();

    if (hosts == null || hosts.length == 0) hosts = new String[] {"::"}; // IPv6 equiv of 0.0.0.0

    String contextPath = getContext().getContextPath();
    if (contextPath == null || "".equals(contextPath)) {
      contextPath = "*";
    }

    _contextId = createContextId(hosts, contextPath);
    this.kvstore_object_ops = new ArrayList<Operation>();
  }
  /*------------------------------------------------------------ */
  @Override
  protected void invalidateSession(String idInCluster) {
    __log.debug("MongoSessionManager:invalidateSession:invalidating " + idInCluster);

    super.invalidateSession(idInCluster);

    /*
     * pull back the 'valid' value, we can check if its false, if is we don't need to
     * reset it to false
     */
    DBObject validKey = new BasicDBObject(__VALID, true);
    DBObject o = _sessions.findOne(new BasicDBObject(__ID, idInCluster), validKey);

    if (o != null && (Boolean) o.get(__VALID)) {
      BasicDBObject update = new BasicDBObject();
      BasicDBObject sets = new BasicDBObject();
      sets.put(__VALID, false);
      sets.put(__INVALIDATED, System.currentTimeMillis());
      update.put("$set", sets);

      BasicDBObject key = new BasicDBObject(__ID, idInCluster);

      _sessions.update(key, update);
    }
  }
  /*------------------------------------------------------------ */
  @Override
  public void doStart() throws Exception {
    super.doStart();
    String[] hosts = getContextHandler().getVirtualHosts();
    // TODO: can this be replaced?
    /*if (hosts == null || hosts.length == 0)
    hosts = getContextHandler().getConnectorNames();*/
    if (hosts == null || hosts.length == 0) hosts = new String[] {"::"}; // IPv6 equiv of 0.0.0.0

    String contextPath = getContext().getContextPath();
    if (contextPath == null || "".equals(contextPath)) {
      contextPath = "*";
    }

    _contextId = createContextId(hosts, contextPath);

    __version_1 = new BasicDBObject(getContextKey(__VERSION), 1);
  }
 /* (non-Javadoc)
  * @see org.eclipse.jetty.server.session.AbstractSessionManager#setSessionIdManager(org.eclipse.jetty.server.SessionIdManager)
  */
 @Override
 public void setSessionIdManager(SessionIdManager metaManager) {
   MongoSessionIdManager msim = (MongoSessionIdManager) metaManager;
   _sessions = msim.getSessions();
   super.setSessionIdManager(metaManager);
 }
  /** @see org.eclipse.jetty.nosql.NoSqlSessionManager#expire(java.lang.String) */
  @Override
  protected void expire(String idInCluster) {
    __log.debug("KVStoreSessionManager:expire session {} ", idInCluster);

    // Expire the session for this context
    super.expire(idInCluster);

    // If the outer session document has not already been marked invalid, do so.
    ValueVersion vver_valid =
        _kvstorehandler.get(
            Key.createKey(Arrays.asList(__storeprefix, idInCluster), Arrays.asList(__VALID)));

    try {
      if (vver_valid != null
          && vver_valid.getValue() != null
          && vver_valid.getValue().getValue() != null
          && "0".equals(new String(vver_valid.getValue().getValue(), "UTF-8"))) {
        if (this.kvstore_opfactory == null)
          this.kvstore_opfactory = this._kvstorehandler.getOperationFactory();
        kvstore_object_ops.clear();
        kvstore_object_ops.add(
            this.kvstore_opfactory.createPut(
                Key.createKey(Arrays.asList(__storeprefix, idInCluster), Arrays.asList(__VALID)),
                Value.createValue("0".getBytes("UTF-8"))));
        kvstore_object_ops.add(
            this.kvstore_opfactory.createPut(
                Key.createKey(
                    Arrays.asList(__storeprefix, idInCluster), Arrays.asList(__INVALIDATED)),
                Value.createValue(
                    Base62Converter.fromBase10(System.currentTimeMillis()).getBytes("UTF-8"))));

        // update indexes
        // delete old entries, if present
        ValueVersion old_valid =
            _kvstorehandler.get(
                Key.createKey(Arrays.asList(__storeprefix, idInCluster), Arrays.asList(__VALID)));
        __log.debug("old_valid=" + (old_valid != null ? "notnull" : "null"));
        ValueVersion old_accessed =
            _kvstorehandler.get(
                Key.createKey(
                    Arrays.asList(__storeprefix, idInCluster), Arrays.asList(__ACCESSED)));
        __log.debug("old_accessed=" + (old_accessed != null ? "notnull" : "null"));
        if (old_valid != null
            && old_valid.getValue() != null
            && old_valid.getValue().getValue() != null
            && old_accessed != null
            && old_accessed.getValue() != null
            && old_accessed.getValue().getValue() != null) {
          __log.debug("deleting old purgeindex entry");
          _kvstorehandler.delete(
              Key.createKey(
                  Arrays.asList(
                      __purgeindexprefix,
                      new String(old_valid.getValue().getValue(), "UTF-8"),
                      new String(old_accessed.getValue().getValue(), "UTF-8")),
                  Arrays.asList(idInCluster)));
        } else __log.debug("some keys for purge index missing, nothing to delete");

        _kvstorehandler.put(
            Key.createKey(
                Arrays.asList(
                    __purgeindexprefix,
                    "0",
                    new String(old_accessed.getValue().getValue(), "UTF-8")),
                Arrays.asList(idInCluster)),
            Value.EMPTY_VALUE);

        if (kvstore_object_ops.size() > 0) {
          _kvstorehandler.execute(kvstore_object_ops);
          kvstore_object_ops.clear();
        }
      }
    } catch (UnsupportedEncodingException | OperationExecutionException | FaultException e) {
      __log.debug(
          "KVStoreSessionManager: expire :: error :: session {} context {} ",
          idInCluster,
          _contextId);
    }
  }