private void generateAccountStatusNotificationForLockedBindAccount(
      Entry userEntry, PasswordPolicyState pwPolicyState) {
    pwPolicyState.updateAuthFailureTimes();
    if (pwPolicyState.lockedDueToFailures()) {
      AccountStatusNotificationType notificationType;
      boolean tempLocked;
      LocalizableMessage m;

      int lockoutDuration = pwPolicyState.getSecondsUntilUnlock();
      if (lockoutDuration > -1) {
        notificationType = AccountStatusNotificationType.ACCOUNT_TEMPORARILY_LOCKED;
        tempLocked = true;
        m = ERR_BIND_ACCOUNT_TEMPORARILY_LOCKED.get(secondsToTimeString(lockoutDuration));
      } else {
        notificationType = AccountStatusNotificationType.ACCOUNT_PERMANENTLY_LOCKED;
        tempLocked = false;
        m = ERR_BIND_ACCOUNT_PERMANENTLY_LOCKED.get();
      }

      pwPolicyState.generateAccountStatusNotification(
          notificationType,
          userEntry,
          m,
          AccountStatusNotification.createProperties(pwPolicyState, tempLocked, -1, null, null));
    }
  }
  /**
   * Perform policy checks for accounts when the credentials are correct.
   *
   * @param userEntry The entry for the user that is authenticating.
   * @param saslHandler The SASL mechanism handler if this is a SASL bind, or {@code null} for a
   *     simple bind.
   * @throws DirectoryException If a problem occurs that should cause the bind to fail.
   */
  protected void checkVerifiedPasswordPolicyState(
      Entry userEntry, SASLMechanismHandler<?> saslHandler) throws DirectoryException {
    PasswordPolicyState pwPolicyState = (PasswordPolicyState) authPolicyState;
    PasswordPolicy policy = pwPolicyState.getAuthenticationPolicy();

    boolean isSASLBind = saslHandler != null;

    // Check to see if the user is administratively disabled or locked.
    if (pwPolicyState.isDisabled()) {
      throw new DirectoryException(
          ResultCode.INVALID_CREDENTIALS, ERR_BIND_OPERATION_ACCOUNT_DISABLED.get());
    } else if (pwPolicyState.isAccountExpired()) {
      LocalizableMessage m = ERR_BIND_OPERATION_ACCOUNT_EXPIRED.get();
      pwPolicyState.generateAccountStatusNotification(
          AccountStatusNotificationType.ACCOUNT_EXPIRED,
          userEntry,
          m,
          AccountStatusNotification.createProperties(pwPolicyState, false, -1, null, null));

      throw new DirectoryException(ResultCode.INVALID_CREDENTIALS, m);
    } else if (pwPolicyState.lockedDueToFailures()) {
      if (pwPolicyErrorType == null) {
        pwPolicyErrorType = PasswordPolicyErrorType.ACCOUNT_LOCKED;
      }

      throw new DirectoryException(
          ResultCode.INVALID_CREDENTIALS, ERR_BIND_OPERATION_ACCOUNT_FAILURE_LOCKED.get());
    } else if (pwPolicyState.lockedDueToIdleInterval()) {
      if (pwPolicyErrorType == null) {
        pwPolicyErrorType = PasswordPolicyErrorType.ACCOUNT_LOCKED;
      }

      LocalizableMessage m = ERR_BIND_OPERATION_ACCOUNT_IDLE_LOCKED.get();
      pwPolicyState.generateAccountStatusNotification(
          AccountStatusNotificationType.ACCOUNT_IDLE_LOCKED,
          userEntry,
          m,
          AccountStatusNotification.createProperties(pwPolicyState, false, -1, null, null));

      throw new DirectoryException(ResultCode.INVALID_CREDENTIALS, m);
    }

    // If it's a simple bind, or if it's a password-based SASL bind, then
    // perform a number of password-based checks.
    if (!isSASLBind || saslHandler.isPasswordBased(saslMechanism)) {
      // Check to see if the account is locked due to the maximum reset age.
      if (pwPolicyState.lockedDueToMaximumResetAge()) {
        if (pwPolicyErrorType == null) {
          pwPolicyErrorType = PasswordPolicyErrorType.ACCOUNT_LOCKED;
        }

        LocalizableMessage m = ERR_BIND_OPERATION_ACCOUNT_RESET_LOCKED.get();
        pwPolicyState.generateAccountStatusNotification(
            AccountStatusNotificationType.ACCOUNT_RESET_LOCKED,
            userEntry,
            m,
            AccountStatusNotification.createProperties(pwPolicyState, false, -1, null, null));

        throw new DirectoryException(ResultCode.INVALID_CREDENTIALS, m);
      }

      // Determine whether the password is expired, or whether the user
      // should be warned about an upcoming expiration.
      if (pwPolicyState.isPasswordExpired()) {
        if (pwPolicyErrorType == null) {
          pwPolicyErrorType = PasswordPolicyErrorType.PASSWORD_EXPIRED;
        }

        int maxGraceLogins = policy.getGraceLoginCount();
        if (maxGraceLogins > 0 && pwPolicyState.mayUseGraceLogin()) {
          List<Long> graceLoginTimes = pwPolicyState.getGraceLoginTimes();
          if (graceLoginTimes == null || graceLoginTimes.size() < maxGraceLogins) {
            isGraceLogin = true;
            mustChangePassword = true;

            if (pwPolicyWarningType == null) {
              pwPolicyWarningType = PasswordPolicyWarningType.GRACE_LOGINS_REMAINING;
              pwPolicyWarningValue = maxGraceLogins - (graceLoginTimes.size() + 1);
            }
          } else {
            LocalizableMessage m = ERR_BIND_OPERATION_PASSWORD_EXPIRED.get();

            pwPolicyState.generateAccountStatusNotification(
                AccountStatusNotificationType.PASSWORD_EXPIRED,
                userEntry,
                m,
                AccountStatusNotification.createProperties(pwPolicyState, false, -1, null, null));

            throw new DirectoryException(ResultCode.INVALID_CREDENTIALS, m);
          }
        } else {
          LocalizableMessage m = ERR_BIND_OPERATION_PASSWORD_EXPIRED.get();

          pwPolicyState.generateAccountStatusNotification(
              AccountStatusNotificationType.PASSWORD_EXPIRED,
              userEntry,
              m,
              AccountStatusNotification.createProperties(pwPolicyState, false, -1, null, null));

          throw new DirectoryException(ResultCode.INVALID_CREDENTIALS, m);
        }
      } else if (pwPolicyState.shouldWarn()) {
        int numSeconds = pwPolicyState.getSecondsUntilExpiration();

        if (pwPolicyWarningType == null) {
          pwPolicyWarningType = PasswordPolicyWarningType.TIME_BEFORE_EXPIRATION;
          pwPolicyWarningValue = numSeconds;
        }

        isFirstWarning = pwPolicyState.isFirstWarning();
      }

      // Check to see if the user's password has been reset.
      if (pwPolicyState.mustChangePassword()) {
        mustChangePassword = true;

        if (pwPolicyErrorType == null) {
          pwPolicyErrorType = PasswordPolicyErrorType.CHANGE_AFTER_RESET;
        }
      }
    }
  }