@Override
  public void recordLogin(User user, String remoteAddr) {
    Vertex userVertex = findByIdUserVertex(user.getUserId());
    ExistingElementMutation<Vertex> m = userVertex.prepareMutation();

    Date currentLoginDate = UserVisalloProperties.CURRENT_LOGIN_DATE.getPropertyValue(userVertex);
    if (currentLoginDate != null) {
      UserVisalloProperties.PREVIOUS_LOGIN_DATE.setProperty(
          m, currentLoginDate, VISIBILITY.getVisibility());
    }

    String currentLoginRemoteAddr =
        UserVisalloProperties.CURRENT_LOGIN_REMOTE_ADDR.getPropertyValue(userVertex);
    if (currentLoginRemoteAddr != null) {
      UserVisalloProperties.PREVIOUS_LOGIN_REMOTE_ADDR.setProperty(
          m, currentLoginRemoteAddr, VISIBILITY.getVisibility());
    }

    UserVisalloProperties.CURRENT_LOGIN_DATE.setProperty(m, new Date(), VISIBILITY.getVisibility());
    UserVisalloProperties.CURRENT_LOGIN_REMOTE_ADDR.setProperty(
        m, remoteAddr, VISIBILITY.getVisibility());

    int loginCount = UserVisalloProperties.LOGIN_COUNT.getPropertyValue(userVertex, 0);
    UserVisalloProperties.LOGIN_COUNT.setProperty(m, loginCount + 1, VISIBILITY.getVisibility());

    m.save(authorizations);
    graph.flush();
  }
 @Override
 public void setPasswordResetTokenAndExpirationDate(User user, String token, Date expirationDate) {
   Vertex userVertex = findByIdUserVertex(user.getUserId());
   UserVisalloProperties.PASSWORD_RESET_TOKEN.setProperty(
       userVertex, token, VISIBILITY.getVisibility(), authorizations);
   UserVisalloProperties.PASSWORD_RESET_TOKEN_EXPIRATION_DATE.setProperty(
       userVertex, expirationDate, VISIBILITY.getVisibility(), authorizations);
   graph.flush();
 }
 @Override
 public void setPassword(User user, String password) {
   byte[] salt = UserPasswordUtil.getSalt();
   byte[] passwordHash = UserPasswordUtil.hashPassword(password, salt);
   Vertex userVertex = findByIdUserVertex(user.getUserId());
   UserVisalloProperties.PASSWORD_SALT.setProperty(
       userVertex, salt, VISIBILITY.getVisibility(), authorizations);
   UserVisalloProperties.PASSWORD_HASH.setProperty(
       userVertex, passwordHash, VISIBILITY.getVisibility(), authorizations);
   graph.flush();
 }
 @Override
 public void setEmailAddress(User user, String emailAddress) {
   Vertex userVertex = findByIdUserVertex(user.getUserId());
   UserVisalloProperties.EMAIL_ADDRESS.setProperty(
       userVertex, emailAddress, VISIBILITY.getVisibility(), authorizations);
   graph.flush();
 }
 @Override
 public void setDisplayName(User user, String displayName) {
   Vertex userVertex = findByIdUserVertex(user.getUserId());
   UserVisalloProperties.DISPLAY_NAME.setProperty(
       userVertex, displayName, VISIBILITY.getVisibility(), authorizations);
   graph.flush();
 }
 @Override
 public void setUiPreferences(User user, JSONObject preferences) {
   Vertex userVertex = findByIdUserVertex(user.getUserId());
   UserVisalloProperties.UI_PREFERENCES.setProperty(
       userVertex, preferences, VISIBILITY.getVisibility(), authorizations);
   graph.flush();
 }
 @Override
 protected void internalSetPrivileges(User user, Set<String> privileges, User authUser) {
   Vertex userVertex = findByIdUserVertex(user.getUserId());
   UserVisalloProperties.PRIVILEGES.setProperty(
       userVertex, Privilege.toString(privileges), VISIBILITY.getVisibility(), authorizations);
   graph.flush();
   userVertexCache.invalidate(user.getUserId());
 }
 @Override
 public User setCurrentWorkspace(String userId, String workspaceId) {
   User user = findById(userId);
   checkNotNull(user, "Could not find user: " + userId);
   Vertex userVertex = findByIdUserVertex(user.getUserId());
   UserVisalloProperties.CURRENT_WORKSPACE.setProperty(
       userVertex, workspaceId, VISIBILITY.getVisibility(), authorizations);
   graph.flush();
   return user;
 }
 @Override
 public void setPropertyOnUser(User user, String propertyName, Object value) {
   if (user instanceof SystemUser) {
     throw new VisalloException("Cannot set properties on system user");
   }
   Vertex userVertex = findByIdUserVertex(user.getUserId());
   userVertex.setProperty(propertyName, value, VISIBILITY.getVisibility(), authorizations);
   if (user instanceof VertexiumUser) {
     ((VertexiumUser) user).setProperty(propertyName, value);
   }
 }
 @Override
 public User setStatus(String userId, UserStatus status) {
   VertexiumUser user = (VertexiumUser) findById(userId);
   checkNotNull(user, "Could not find user: " + userId);
   Vertex userVertex = findByIdUserVertex(user.getUserId());
   UserVisalloProperties.STATUS.setProperty(
       userVertex, status.toString(), VISIBILITY.getVisibility(), authorizations);
   graph.flush();
   user.setUserStatus(status);
   return user;
 }
 @Override
 public void internalRemoveAuthorization(User user, String auth, User authUser) {
   Vertex userVertex = findByIdUserVertex(user.getUserId());
   Set<String> authorizationSet = getAuthorizations(userVertex);
   if (!authorizationSet.contains(auth)) {
     return;
   }
   authorizationSet.remove(auth);
   String authorizationsString = StringUtils.join(authorizationSet, ",");
   UserVisalloProperties.AUTHORIZATIONS.setProperty(
       userVertex, authorizationsString, VISIBILITY.getVisibility(), authorizations);
   graph.flush();
   userVertexCache.invalidate(user.getUserId());
 }
  @Override
  protected User addUser(
      String username,
      String displayName,
      String emailAddress,
      String password,
      String[] userAuthorizations) {
    username = formatUsername(username);
    displayName = displayName.trim();
    String authorizationsString = StringUtils.join(userAuthorizations, ",");

    byte[] salt = UserPasswordUtil.getSalt();
    byte[] passwordHash = UserPasswordUtil.hashPassword(password, salt);

    String id = GRAPH_USER_ID_PREFIX + graph.getIdGenerator().nextId();
    VertexBuilder userBuilder = graph.prepareVertex(id, VISIBILITY.getVisibility());

    VisalloProperties.CONCEPT_TYPE.setProperty(
        userBuilder, userConceptId, VISIBILITY.getVisibility());
    UserVisalloProperties.USERNAME.setProperty(userBuilder, username, VISIBILITY.getVisibility());
    UserVisalloProperties.DISPLAY_NAME.setProperty(
        userBuilder, displayName, VISIBILITY.getVisibility());
    UserVisalloProperties.CREATE_DATE.setProperty(
        userBuilder, new Date(), VISIBILITY.getVisibility());
    UserVisalloProperties.PASSWORD_SALT.setProperty(userBuilder, salt, VISIBILITY.getVisibility());
    UserVisalloProperties.PASSWORD_HASH.setProperty(
        userBuilder, passwordHash, VISIBILITY.getVisibility());
    UserVisalloProperties.STATUS.setProperty(
        userBuilder, UserStatus.OFFLINE.toString(), VISIBILITY.getVisibility());
    UserVisalloProperties.AUTHORIZATIONS.setProperty(
        userBuilder, authorizationsString, VISIBILITY.getVisibility());
    UserVisalloProperties.PRIVILEGES.setProperty(
        userBuilder, Privilege.toString(getDefaultPrivileges()), VISIBILITY.getVisibility());

    if (emailAddress != null) {
      UserVisalloProperties.EMAIL_ADDRESS.setProperty(
          userBuilder, emailAddress, VISIBILITY.getVisibility());
    }

    User user = createFromVertex(userBuilder.save(this.authorizations));
    graph.flush();

    afterNewUserAdded(user);

    return user;
  }