/** This method is used to check pre conditions when changing the user password. */
  public boolean doPreUpdateCredential(
      String userName,
      Object newCredential,
      Object oldCredential,
      UserStoreManager userStoreManager)
      throws UserStoreException {

    if (log.isDebugEnabled()) {
      log.debug("Pre update credential is called in IdentityMgtEventListener");
    }

    IdentityMgtConfig config = IdentityMgtConfig.getInstance();
    if (!config.isListenerEnable()) {
      return true;
    }

    try {
      // Enforcing the password policies.
      if (newCredential != null
          && (newCredential instanceof String && (newCredential.toString().trim().length() > 0))) {
        policyRegistry.enforcePasswordPolicies(newCredential.toString(), userName);
      }

    } catch (PolicyViolationException pe) {
      log.error(pe.getMessage());
      throw new UserStoreException(pe.getMessage());
    }

    return true;
  }
  /**
   * This method is used when the admin is updating the credentials with an empty credential. A
   * random password will be generated and will be mailed to the user.
   */
  @Override
  public boolean doPreUpdateCredentialByAdmin(
      String userName, Object newCredential, UserStoreManager userStoreManager)
      throws UserStoreException {

    if (log.isDebugEnabled()) {
      log.debug("Pre update credential by admin is called in IdentityMgtEventListener");
    }
    IdentityMgtConfig config = IdentityMgtConfig.getInstance();
    if (!config.isListenerEnable()) {
      return true;
    }

    try {
      // Enforcing the password policies.
      if (newCredential != null
          && (newCredential instanceof StringBuffer
              && (newCredential.toString().trim().length() > 0))) {
        policyRegistry.enforcePasswordPolicies(newCredential.toString(), userName);
      }

    } catch (PolicyViolationException pe) {
      log.error(pe.getMessage());
      throw new UserStoreException(pe.getMessage());
    }

    if (newCredential == null
        || (newCredential instanceof StringBuffer
            && ((StringBuffer) newCredential).toString().trim().length() < 1)) {

      if (!config.isEnableTemporaryPassword()) {
        log.error("Empty passwords are not allowed");
        return false;
      }
      if (log.isDebugEnabled()) {
        log.debug("Credentials are null. Using a temporary password as credentials");
      }
      // temporary passwords will be used
      char[] temporaryPassword = UserIdentityManagementUtil.generateTemporaryPassword();
      // setting the password value
      ((StringBuffer) newCredential)
          .replace(0, temporaryPassword.length, new String(temporaryPassword));

      UserIdentityMgtBean bean = new UserIdentityMgtBean();
      bean.setUserId(userName);
      bean.setConfirmationCode(newCredential.toString());
      bean.setRecoveryType(IdentityMgtConstants.Notification.TEMPORARY_PASSWORD);
      log.debug("Sending the tempory password to the user " + userName);
      UserIdentityManagementUtil.notifyViaEmail(bean);
    } else {
      log.debug("Updating credentials of user " + userName + " by admin with a non-empty password");
    }
    return true;
  }
  /**
   * This method will set the default/random password if the password provided is null. The thread
   * local parameter EMPTY_PASSWORD_USED will be used to track if the password empty in the
   * doPostAddUser. This method will filter the security question URIs from claims and put those to
   * the thread local properties.
   */
  @Override
  public boolean doPreAddUser(
      String userName,
      Object credential,
      String[] roleList,
      Map<String, String> claims,
      String profile,
      UserStoreManager userStoreManager)
      throws UserStoreException {

    if (log.isDebugEnabled()) {
      log.debug("Pre add user is called in IdentityMgtEventListener");
    }
    IdentityMgtConfig config = IdentityMgtConfig.getInstance();
    if (!config.isListenerEnable()) {
      return true;
    }

    try {
      // Enforcing the password policies.
      if (credential != null
          && (credential instanceof StringBuffer && (credential.toString().trim().length() > 0))) {
        policyRegistry.enforcePasswordPolicies(credential.toString(), userName);
      }

    } catch (PolicyViolationException pe) {
      log.error(pe.getMessage());
      throw new UserStoreException(pe.getMessage());
    }

    // empty password account creation
    if (credential == null
        || (credential instanceof StringBuffer && (credential.toString().trim().length() < 1))) {

      if (!config.isEnableTemporaryPassword()) {
        log.error("Empty passwords are not allowed");
        return false;
      }
      if (log.isDebugEnabled()) {
        log.debug("Credentials are null. Using a temporary password as credentials");
      }
      // setting the thread-local to check in doPostAddUser
      threadLocalProperties.get().put(EMPTY_PASSWORD_USED, true);
      // temporary passwords will be used
      char[] temporaryPassword = UserIdentityManagementUtil.generateTemporaryPassword();

      // setting the password value
      ((StringBuffer) credential)
          .replace(0, temporaryPassword.length, new String(temporaryPassword));
    }

    // Filtering security question URIs from claims and add them to the thread local dto
    Map<String, String> userDataMap = new HashMap<String, String>();

    // TODO why challenge Q
    Iterator<Entry<String, String>> it = claims.entrySet().iterator();
    while (it.hasNext()) {

      Map.Entry<String, String> claim = it.next();

      if (claim.getKey().contains(UserCoreConstants.ClaimTypeURIs.CHALLENGE_QUESTION_URI)
          || claim.getKey().contains(UserCoreConstants.ClaimTypeURIs.IDENTITY_CLAIM_URI)) {
        userDataMap.put(claim.getKey(), claim.getValue());
        it.remove();
      }
    }

    UserIdentityClaimsDO identityDTO = new UserIdentityClaimsDO(userName, userDataMap);
    // adding dto to thread local to be read again from the doPostAddUser method
    threadLocalProperties.get().put(USER_IDENTITY_DO, identityDTO);
    return true;
  }