@Override
  public void updateSessionAttributes(String id, AttributeUpdater updater)
      throws WrongArgumentException {
    Object transaction = tokensManagement.startTokenTransaction();
    try {
      Token token = tokensManagement.getTokenById(SESSION_TOKEN_TYPE, id, transaction);
      LoginSession session = token2session(token);

      updater.updateAttributes(session.getSessionData());

      byte[] contents = session.getTokenContents();
      tokensManagement.updateToken(SESSION_TOKEN_TYPE, id, null, contents, transaction);
      tokensManagement.commitTokenTransaction(transaction);
    } finally {
      tokensManagement.closeTokenTransaction(transaction);
    }
  }
  @Override
  public void updateSessionActivity(String id) throws WrongArgumentException {
    Long lastWrite = recentUsageUpdates.get(id);
    if (lastWrite != null) {
      if (System.currentTimeMillis() < lastWrite + DB_ACTIVITY_WRITE_DELAY) return;
    }

    Object transaction = tokensManagement.startTokenTransaction();
    try {
      Token token = tokensManagement.getTokenById(SESSION_TOKEN_TYPE, id, transaction);
      LoginSession session = token2session(token);
      session.setLastUsed(new Date());
      byte[] contents = session.getTokenContents();
      tokensManagement.updateToken(SESSION_TOKEN_TYPE, id, null, contents, transaction);
      tokensManagement.commitTokenTransaction(transaction);
      log.trace("Updated in db session activity timestamp for " + id);
      recentUsageUpdates.put(id, System.currentTimeMillis());
    } finally {
      tokensManagement.closeTokenTransaction(transaction);
    }
  }
 @Override
 public LoginSession getSession(String id) throws WrongArgumentException {
   Token token = tokensManagement.getTokenById(SESSION_TOKEN_TYPE, id, null);
   return token2session(token);
 }