private boolean invokePreOpPlugins() {
   executePostOpPlugins = true;
   PluginResult.PreOperation preOpResult = pluginConfigManager.invokePreOperationBindPlugins(this);
   if (!preOpResult.continueProcessing()) {
     setResultCode(preOpResult.getResultCode());
     appendErrorMessage(preOpResult.getErrorMessage());
     setMatchedDN(preOpResult.getMatchedDN());
     setReferralURLs(preOpResult.getReferralURLs());
     return false;
   } else {
     return true;
   }
 }
  /**
   * Process this bind operation in a local backend.
   *
   * @param wfe The local backend work-flow element.
   */
  public void processLocalBind(LocalBackendWorkflowElement wfe) {
    this.backend = wfe.getBackend();

    // Initialize a number of variables for use during the bind processing.
    clientConnection = getClientConnection();
    returnAuthzID = false;
    executePostOpPlugins = false;
    sizeLimit = DirectoryServer.getSizeLimit();
    timeLimit = DirectoryServer.getTimeLimit();
    lookthroughLimit = DirectoryServer.getLookthroughLimit();
    idleTimeLimit = DirectoryServer.getIdleTimeLimit();
    bindDN = getBindDN();
    saslMechanism = getSASLMechanism();
    authPolicyState = null;
    pwPolicyErrorType = null;
    pwPolicyControlRequested = false;
    isGraceLogin = false;
    isFirstWarning = false;
    mustChangePassword = false;
    pwPolicyWarningType = null;
    pwPolicyWarningValue = -1;
    pluginConfigManager = DirectoryServer.getPluginConfigManager();

    processBind();

    // Update the user's account with any password policy changes that may be
    // required.
    try {
      if (authPolicyState != null) {
        authPolicyState.finalizeStateAfterBind();
      }
    } catch (DirectoryException de) {
      logger.traceException(de);

      setResponseData(de);
    }

    // Invoke the post-operation bind plugins.
    if (executePostOpPlugins) {
      PluginResult.PostOperation postOpResult =
          pluginConfigManager.invokePostOperationBindPlugins(this);
      if (!postOpResult.continueProcessing()) {
        setResultCode(postOpResult.getResultCode());
        appendErrorMessage(postOpResult.getErrorMessage());
        setMatchedDN(postOpResult.getMatchedDN());
        setReferralURLs(postOpResult.getReferralURLs());
      }
    }

    // Update the authentication information for the user.
    AuthenticationInfo authInfo = getAuthenticationInfo();
    if (getResultCode() == ResultCode.SUCCESS && authInfo != null) {
      clientConnection.setAuthenticationInfo(authInfo);
      clientConnection.setSizeLimit(sizeLimit);
      clientConnection.setTimeLimit(timeLimit);
      clientConnection.setIdleTimeLimit(idleTimeLimit);
      clientConnection.setLookthroughLimit(lookthroughLimit);
      clientConnection.setMustChangePassword(mustChangePassword);

      if (returnAuthzID) {
        addResponseControl(new AuthorizationIdentityResponseControl(authInfo.getAuthorizationDN()));
      }
    }

    // See if we need to send a password policy control to the client.  If so,
    // then add it to the response.
    if (getResultCode() == ResultCode.SUCCESS) {
      if (pwPolicyControlRequested) {
        PasswordPolicyResponseControl pwpControl =
            new PasswordPolicyResponseControl(
                pwPolicyWarningType, pwPolicyWarningValue, pwPolicyErrorType);
        addResponseControl(pwpControl);
      } else {
        if (pwPolicyErrorType == PasswordPolicyErrorType.PASSWORD_EXPIRED) {
          addResponseControl(new PasswordExpiredControl());
        } else if (pwPolicyWarningType == PasswordPolicyWarningType.TIME_BEFORE_EXPIRATION) {
          addResponseControl(new PasswordExpiringControl(pwPolicyWarningValue));
        } else if (mustChangePassword) {
          addResponseControl(new PasswordExpiredControl());
        }
      }
    } else {
      if (pwPolicyControlRequested) {
        PasswordPolicyResponseControl pwpControl =
            new PasswordPolicyResponseControl(
                pwPolicyWarningType, pwPolicyWarningValue, pwPolicyErrorType);
        addResponseControl(pwpControl);
      } else {
        if (pwPolicyErrorType == PasswordPolicyErrorType.PASSWORD_EXPIRED) {
          addResponseControl(new PasswordExpiredControl());
        }
      }
    }
  }
  /**
   * Performs the work of actually processing this operation. This should include all processing for
   * the operation, including invoking plugins, logging messages, performing access control,
   * managing synchronization, and any other work that might need to be done in the course of
   * processing.
   */
  public final void run() {
    setResultCode(ResultCode.UNDEFINED);

    // Start the processing timer.
    setProcessingStartTime();

    // Log the abandon request message.
    logAbandonRequest(this);

    // Get the plugin config manager that will be used for invoking plugins.
    PluginConfigManager pluginConfigManager = DirectoryServer.getPluginConfigManager();

    // Create a labeled block of code that we can break out of if a problem is
    // detected.
    abandonProcessing:
    {
      // Invoke the pre-parse abandon plugins.
      PluginResult.PreParse preParseResult = pluginConfigManager.invokePreParseAbandonPlugins(this);
      if (!preParseResult.continueProcessing()) {
        setResultCode(preParseResult.getResultCode());
        appendErrorMessage(preParseResult.getErrorMessage());
        setMatchedDN(preParseResult.getMatchedDN());
        setReferralURLs(preParseResult.getReferralURLs());
        break abandonProcessing;
      }

      // Actually perform the abandon operation.  Make sure to set the result
      // code to reflect whether the abandon was successful and an error message
      // if it was not.  Even though there is no response, the result should
      // still be logged.
      //
      // Even though it is technically illegal to send a response for
      // operations that have been abandoned, it may be a good idea to do so
      // to ensure that the requestor isn't left hanging.  This will be a
      // configurable option in the server.
      boolean notifyRequestor = DirectoryServer.notifyAbandonedOperations();

      Message cancelReason = INFO_CANCELED_BY_ABANDON_REQUEST.get(messageID);

      CancelRequest _cancelRequest = new CancelRequest(notifyRequestor, cancelReason);

      CancelResult result = clientConnection.cancelOperation(idToAbandon, _cancelRequest);

      setResultCode(result.getResultCode());
      appendErrorMessage(result.getResponseMessage());

      PluginResult.PostOperation postOpResult =
          pluginConfigManager.invokePostOperationAbandonPlugins(this);
      if (!postOpResult.continueProcessing()) {
        setResultCode(preParseResult.getResultCode());
        appendErrorMessage(preParseResult.getErrorMessage());
        setMatchedDN(preParseResult.getMatchedDN());
        setReferralURLs(preParseResult.getReferralURLs());
        break abandonProcessing;
      }
    }

    // Stop the processing timer.
    setProcessingStopTime();

    // Log the result of the abandon operation.
    logAbandonResult(this);
  }