From fbda6e0892dcfcc8dd43d21f6fb134aabb8d0cac Mon Sep 17 00:00:00 2001
From: jarnou <jarnou@localhost>
Date: Tue, 03 Jul 2007 09:29:17 +0000
Subject: [PATCH] Commits the refactoring of the core server to provide support for proxy/distribution/virtual functionnalities. This includes the new set of local operations, as well as the workflow and networkgroup support.

---
 opends/src/server/org/opends/server/core/BindOperation.java | 2244 +----------------------------------------------------------
 1 files changed, 39 insertions(+), 2,205 deletions(-)

diff --git a/opends/src/server/org/opends/server/core/BindOperation.java b/opends/src/server/org/opends/server/core/BindOperation.java
index a62bff4..03cf58b 100644
--- a/opends/src/server/org/opends/server/core/BindOperation.java
+++ b/opends/src/server/org/opends/server/core/BindOperation.java
@@ -26,414 +26,33 @@
  */
 package org.opends.server.core;
 
-
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.concurrent.locks.Lock;
-
-import org.opends.server.api.ClientConnection;
-import org.opends.server.api.SASLMechanismHandler;
-import org.opends.server.api.plugin.PostOperationPluginResult;
-import org.opends.server.api.plugin.PreOperationPluginResult;
-import org.opends.server.api.plugin.PreParsePluginResult;
-import org.opends.server.controls.AuthorizationIdentityResponseControl;
-import org.opends.server.controls.PasswordExpiredControl;
-import org.opends.server.controls.PasswordExpiringControl;
-import org.opends.server.controls.PasswordPolicyErrorType;
-import org.opends.server.controls.PasswordPolicyResponseControl;
-import org.opends.server.controls.PasswordPolicyWarningType;
 import org.opends.server.protocols.asn1.ASN1OctetString;
-import org.opends.server.types.AccountStatusNotificationType;
-import org.opends.server.types.Attribute;
-import org.opends.server.types.AttributeType;
-import org.opends.server.types.AttributeValue;
 import org.opends.server.types.AuthenticationInfo;
 import org.opends.server.types.AuthenticationType;
 import org.opends.server.types.ByteString;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DisconnectReason;
 import org.opends.server.types.DN;
 import org.opends.server.types.Entry;
-import org.opends.server.types.ErrorLogCategory;
-import org.opends.server.types.ErrorLogSeverity;
-import org.opends.server.types.LockManager;
 import org.opends.server.types.Operation;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.operation.PostOperationBindOperation;
-import org.opends.server.types.operation.PostResponseBindOperation;
-import org.opends.server.types.operation.PreOperationBindOperation;
-import org.opends.server.types.operation.PreParseBindOperation;
-
-import static org.opends.server.config.ConfigConstants.*;
-import static org.opends.server.core.CoreConstants.*;
-import static org.opends.server.loggers.AccessLogger.*;
-import static org.opends.server.loggers.ErrorLogger.*;
-import static org.opends.server.loggers.debug.DebugLogger.*;
-import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.DebugLogLevel;
-import static org.opends.server.messages.CoreMessages.*;
-import static org.opends.server.messages.MessageHandler.*;
-import static org.opends.server.util.ServerConstants.*;
-import static org.opends.server.util.StaticUtils.*;
-
-
-
 
 /**
- * This class defines an operation that may be used to authenticate a user to
- * the Directory Server.  Note that for security restrictions, response messages
- * that may be returned to the client must be carefully cleaned to ensure that
- * they do not provide a malicious client with information that may be useful in
- * an attack.  This does impact the debugability of the server, but that can
- * be addressed by calling the <CODE>setAuthFailureReason</CODE> method, which
- * can provide a reason for a failure in a form that will not be returned to the
- * client but may be written to a log file.
+ * This interface defines an operation that may be used to authenticate a user
+ * to the Directory Server.  Note that for security restrictions, response
+ * messages that may be returned to the client must be carefully cleaned to
+ * ensure that they do not provide a malicious client with information that may
+ * be useful in an attack.  This does impact the debugability of the server,
+ * but that can be addressed by calling the <CODE>setAuthFailureReason</CODE>
+ * method, which can provide a reason for a failure in a form that will not be
+ * returned to the client but may be written to a log file.
  */
-public class BindOperation
-             extends Operation
-             implements PreParseBindOperation, PreOperationBindOperation,
-                        PostOperationBindOperation, PostResponseBindOperation
+public interface BindOperation extends Operation
 {
-  /**
-   * The tracer object for the debug logger.
-   */
-  private static final DebugTracer TRACER = getTracer();
-
-  // The credentials used for SASL authentication.
-  private ASN1OctetString saslCredentials;
-
-  // The server SASL credentials provided to the client in the response.
-  private ASN1OctetString serverSASLCredentials;
-
-  // The authentication info for this bind operation.
-  private AuthenticationInfo authInfo;
-
-  // The authentication type used for this bind operation.
-  private AuthenticationType authType;
-
-  // Indicates whether the warning notification that should be sent to the user
-  // would be the first warning.
-  private boolean isFirstWarning;
-
-  // Indicates whether the authentication should use a grace login if it is
-  // successful.
-  private boolean isGraceLogin;
-
-  // Indicates whether the user's password must be changed before any other
-  // operations will be allowed.
-  private boolean mustChangePassword;
-
-  // Indicates whether the client included the password policy control in the
-  // bind request.
-  private boolean pwPolicyControlRequested;
-
-  // The raw, unprocessed bind DN as contained in the client request.
-  private ByteString rawBindDN;
-
-  // The password used for simple authentication.
-  private ByteString simplePassword;
-
-  // The bind DN used for this bind operation.
-  private DN bindDN;
-
-  // The DN of the user entry that is attempting to authenticate.
-  private DN userEntryDN;
-
-  // The entry of the user that successfully authenticated during processing of
-  // this bind operation.
-  private Entry authenticatedUserEntry;
-
-  // The DN of the user as whom a SASL authentication was attempted (regardless
-  // of whether the authentication was successful) for the purpose of updating
-  // password policy state information.
-  private Entry saslAuthUserEntry;
-
-  // The unique ID associated with the failure reason message.
-  private int authFailureID;
-
-  // The password policy warning value that should be included in the response
-  // control.
-  private int pwPolicyWarningValue;
-
-  // The set of response controls for this bind operation.
-  private List<Control> responseControls;
-
-  // The time that processing started on this operation.
-  private long processingStartTime;
-
-  // The time that processing ended on this operation.
-  private long processingStopTime;
-
-  // The password policy error type that should be included in the response
-  // control
-  private PasswordPolicyErrorType pwPolicyErrorType;
-
-  // The password policy warning type that should be included in the response
-  // control
-  private PasswordPolicyWarningType pwPolicyWarningType;
-
-  // The password policy state information for this bind operation.
-  private PasswordPolicyState pwPolicyState;
-
-  // A message explaining the reason for the authentication failure.
-  private String authFailureReason;
-
-  // A string representation of the protocol version for this bind operation.
-  private String protocolVersion;
-
-  // The SASL mechanism used for SASL authentication.
-  private String saslMechanism;
-
-
-
-  /**
-   * Creates a new simple bind operation with the provided information.
-   *
-   * @param  clientConnection  The client connection with which this operation
-   *                           is associated.
-   * @param  operationID       The operation ID for this operation.
-   * @param  messageID         The message ID of the request with which this
-   *                           operation is associated.
-   * @param  requestControls   The set of controls included in the request.
-   * @param  protocolVersion   The string representation of the protocol version
-   *                           associated with this bind request.
-   * @param  rawBindDN         The raw, unprocessed bind DN as provided in the
-   *                           request from the client.
-   * @param  simplePassword    The password to use for the simple
-   *                           authentication.
-   */
-  public BindOperation(ClientConnection clientConnection, long operationID,
-                       int messageID, List<Control> requestControls,
-                       String protocolVersion, ByteString rawBindDN,
-                       ByteString simplePassword)
-  {
-    super(clientConnection, operationID, messageID, requestControls);
-
-
-    this.protocolVersion = protocolVersion;
-    this.authType        = AuthenticationType.SIMPLE;
-    this.saslMechanism   = null;
-    this.saslCredentials = null;
-
-    if (rawBindDN == null)
-    {
-      this.rawBindDN = new ASN1OctetString();
-    }
-    else
-    {
-      this.rawBindDN = rawBindDN;
-    }
-
-    if (simplePassword == null)
-    {
-      this.simplePassword = new ASN1OctetString();
-    }
-    else
-    {
-      this.simplePassword = simplePassword;
-    }
-
-    bindDN                   = null;
-    userEntryDN              = null;
-    responseControls         = new ArrayList<Control>(0);
-    authFailureID            = 0;
-    authFailureReason        = null;
-    authenticatedUserEntry   = null;
-    saslAuthUserEntry        = null;
-    isFirstWarning           = false;
-    isGraceLogin             = false;
-    mustChangePassword       = false;
-    pwPolicyControlRequested = false;
-    pwPolicyErrorType        = null;
-    pwPolicyWarningType      = null;
-    pwPolicyWarningValue     = -1;
-  }
-
-
-
-  /**
-   * Creates a new SASL bind operation with the provided information.
-   *
-   * @param  clientConnection  The client connection with which this operation
-   *                           is associated.
-   * @param  operationID       The operation ID for this operation.
-   * @param  messageID         The message ID of the request with which this
-   *                           operation is associated.
-   * @param  requestControls   The set of controls included in the request.
-   * @param  protocolVersion   The string representation of the protocol version
-   *                           associated with this bind request.
-   * @param  rawBindDN         The raw, unprocessed bind DN as provided in the
-   *                           request from the client.
-   * @param  saslMechanism     The SASL mechanism included in the request.
-   * @param  saslCredentials   The optional SASL credentials included in the
-   *                           request.
-   */
-  public BindOperation(ClientConnection clientConnection, long operationID,
-                       int messageID, List<Control> requestControls,
-                       String protocolVersion, ByteString rawBindDN,
-                       String saslMechanism, ASN1OctetString saslCredentials)
-  {
-    super(clientConnection, operationID, messageID, requestControls);
-
-
-    this.protocolVersion = protocolVersion;
-    this.authType        = AuthenticationType.SASL;
-    this.saslMechanism   = saslMechanism;
-    this.saslCredentials = saslCredentials;
-    this.simplePassword  = null;
-
-    if (rawBindDN == null)
-    {
-      this.rawBindDN = new ASN1OctetString();
-    }
-    else
-    {
-      this.rawBindDN = rawBindDN;
-    }
-
-    bindDN                 = null;
-    userEntryDN            = null;
-    responseControls       = new ArrayList<Control>(0);
-    authFailureID          = 0;
-    authFailureReason      = null;
-    authenticatedUserEntry = null;
-    saslAuthUserEntry      = null;
-  }
-
-
-
-  /**
-   * Creates a new simple bind operation with the provided information.
-   *
-   * @param  clientConnection  The client connection with which this operation
-   *                           is associated.
-   * @param  operationID       The operation ID for this operation.
-   * @param  messageID         The message ID of the request with which this
-   *                           operation is associated.
-   * @param  requestControls   The set of controls included in the request.
-   * @param  protocolVersion   The string representation of the protocol version
-   *                           associated with this bind request.
-   * @param  bindDN            The bind DN for this bind operation.
-   * @param  simplePassword    The password to use for the simple
-   *                           authentication.
-   */
-  public BindOperation(ClientConnection clientConnection, long operationID,
-                       int messageID, List<Control> requestControls,
-                       String protocolVersion, DN bindDN,
-                       ByteString simplePassword)
-  {
-    super(clientConnection, operationID, messageID, requestControls);
-
-
-    this.protocolVersion = protocolVersion;
-    this.authType        = AuthenticationType.SIMPLE;
-    this.bindDN          = bindDN;
-    this.saslMechanism   = null;
-    this.saslCredentials = null;
-
-    if (bindDN == null)
-    {
-      rawBindDN = new ASN1OctetString();
-    }
-    else
-    {
-      rawBindDN = new ASN1OctetString(bindDN.toString());
-    }
-
-    if (simplePassword == null)
-    {
-      this.simplePassword = new ASN1OctetString();
-    }
-    else
-    {
-      this.simplePassword = simplePassword;
-    }
-
-    responseControls         = new ArrayList<Control>(0);
-    authFailureID            = 0;
-    authFailureReason        = null;
-    authenticatedUserEntry   = null;
-    saslAuthUserEntry        = null;
-    isFirstWarning           = false;
-    isGraceLogin             = false;
-    mustChangePassword       = false;
-    pwPolicyControlRequested = false;
-    pwPolicyErrorType        = null;
-    pwPolicyWarningType      = null;
-    pwPolicyWarningValue     = -1;
-    userEntryDN              = null;
-  }
-
-
-
-  /**
-   * Creates a new SASL bind operation with the provided information.
-   *
-   * @param  clientConnection  The client connection with which this operation
-   *                           is associated.
-   * @param  operationID       The operation ID for this operation.
-   * @param  messageID         The message ID of the request with which this
-   *                           operation is associated.
-   * @param  requestControls   The set of controls included in the request.
-   * @param  protocolVersion   The string representation of the protocol version
-   *                           associated with this bind request.
-   * @param  bindDN            The bind DN for this bind operation.
-   * @param  saslMechanism     The SASL mechanism included in the request.
-   * @param  saslCredentials   The optional SASL credentials included in the
-   *                           request.
-   */
-  public BindOperation(ClientConnection clientConnection, long operationID,
-                       int messageID, List<Control> requestControls,
-                       String protocolVersion, DN bindDN,
-                       String saslMechanism, ASN1OctetString saslCredentials)
-  {
-    super(clientConnection, operationID, messageID, requestControls);
-
-
-    this.protocolVersion = protocolVersion;
-    this.authType        = AuthenticationType.SASL;
-    this.bindDN          = bindDN;
-    this.saslMechanism   = saslMechanism;
-    this.saslCredentials = saslCredentials;
-    this.simplePassword  = null;
-
-    if (bindDN == null)
-    {
-      rawBindDN = new ASN1OctetString();
-    }
-    else
-    {
-      rawBindDN = new ASN1OctetString(bindDN.toString());
-    }
-
-    responseControls       = new ArrayList<Control>(0);
-    authFailureID          = 0;
-    authFailureReason      = null;
-    authenticatedUserEntry = null;
-    saslAuthUserEntry      = null;
-    userEntryDN            = null;
-  }
-
-
 
   /**
    * Retrieves the authentication type for this bind operation.
    *
    * @return  The authentication type for this bind operation.
    */
-  public final AuthenticationType getAuthenticationType()
-  {
-    return authType;
-  }
-
-
+  public abstract AuthenticationType getAuthenticationType();
 
   /**
    * Retrieves the raw, unprocessed bind DN for this bind operation as contained
@@ -443,12 +62,7 @@
    * @return  The raw, unprocessed bind DN for this bind operation as contained
    *          in the client request.
    */
-  public final ByteString getRawBindDN()
-  {
-    return rawBindDN;
-  }
-
-
+  public abstract ByteString getRawBindDN();
 
   /**
    * Specifies the raw, unprocessed bind DN for this bind operation.  This
@@ -456,21 +70,7 @@
    *
    * @param  rawBindDN  The raw, unprocessed bind DN for this bind operation.
    */
-  public final void setRawBindDN(ByteString rawBindDN)
-  {
-    if (rawBindDN == null)
-    {
-      this.rawBindDN = new ASN1OctetString();
-    }
-    else
-    {
-      this.rawBindDN = rawBindDN;
-    }
-
-    bindDN = null;
-  }
-
-
+  public abstract void setRawBindDN(ByteString rawBindDN);
 
   /**
    * Retrieves a string representation of the protocol version associated with
@@ -479,12 +79,7 @@
    * @return  A string representation of the protocol version associated with
    *          this bind request.
    */
-  public String getProtocolVersion()
-  {
-    return protocolVersion;
-  }
-
-
+  public String getProtocolVersion();
 
   /**
    * Specifies the string representation of the protocol version associated with
@@ -493,12 +88,7 @@
    * @param  protocolVersion  The string representation of the protocol version
    *                          associated with this bind request.
    */
-  public void setProtocolVersion(String protocolVersion)
-  {
-    this.protocolVersion = protocolVersion;
-  }
-
-
+  public void setProtocolVersion(String protocolVersion);
 
   /**
    * Retrieves the bind DN for this bind operation.  This method should not be
@@ -509,24 +99,14 @@
    * @return  The bind DN for this bind operation, or <CODE>null</CODE> if the
    *          raw DN has not yet been processed.
    */
-  public final DN getBindDN()
-  {
-    return bindDN;
-  }
-
-
+  public abstract DN getBindDN();
 
   /**
    * Retrieves the simple authentication password for this bind operation.
    *
    * @return  The simple authentication password for this bind operation.
    */
-  public final ByteString getSimplePassword()
-  {
-    return simplePassword;
-  }
-
-
+  public abstract ByteString getSimplePassword();
 
   /**
    * Specifies the simple authentication password for this bind operation.
@@ -534,23 +114,7 @@
    * @param  simplePassword  The simple authentication password for this bind
    *                         operation.
    */
-  public final void setSimplePassword(ByteString simplePassword)
-  {
-    if (simplePassword == null)
-    {
-      this.simplePassword = new ASN1OctetString();
-    }
-    else
-    {
-      this.simplePassword = simplePassword;
-    }
-
-    authType        = AuthenticationType.SIMPLE;
-    saslMechanism   = null;
-    saslCredentials = null;
-  }
-
-
+  public abstract void setSimplePassword(ByteString simplePassword);
 
   /**
    * Retrieves the SASL mechanism for this bind operation.
@@ -558,12 +122,7 @@
    * @return  The SASL mechanism for this bind operation, or <CODE>null</CODE>
    *          if the bind does not use SASL authentication.
    */
-  public final String getSASLMechanism()
-  {
-    return  saslMechanism;
-  }
-
-
+  public abstract String getSASLMechanism();
 
   /**
    * Retrieves the SASL credentials for this bind operation.
@@ -571,12 +130,7 @@
    * @return  The SASL credentials for this bind operation, or <CODE>null</CODE>
    *          if there are none or if the bind does not use SASL authentication.
    */
-  public final ASN1OctetString getSASLCredentials()
-  {
-    return saslCredentials;
-  }
-
-
+  public abstract ASN1OctetString getSASLCredentials();
 
   /**
    * Specifies the SASL credentials for this bind operation.
@@ -585,17 +139,8 @@
    * @param  saslCredentials  The SASL credentials for this bind operation, or
    *                          <CODE>null</CODE> if there are none.
    */
-  public final void setSASLCredentials(String saslMechanism,
-                                       ASN1OctetString saslCredentials)
-  {
-    this.saslMechanism   = saslMechanism;
-    this.saslCredentials = saslCredentials;
-
-    authType       = AuthenticationType.SASL;
-    simplePassword = null;
-  }
-
-
+  public abstract void setSASLCredentials(String saslMechanism,
+      ASN1OctetString saslCredentials);
 
   /**
    * Retrieves the set of server SASL credentials to include in the bind
@@ -604,12 +149,7 @@
    * @return  The set of server SASL credentials to include in the bind
    *          response, or <CODE>null</CODE> if there are none.
    */
-  public final ASN1OctetString getServerSASLCredentials()
-  {
-    return serverSASLCredentials;
-  }
-
-
+  public abstract ASN1OctetString getServerSASLCredentials();
 
   /**
    * Specifies the set of server SASL credentials to include in the bind
@@ -618,13 +158,8 @@
    * @param  serverSASLCredentials  The set of server SASL credentials to
    *                                include in the bind response.
    */
-  public final void setServerSASLCredentials(ASN1OctetString
-                                                  serverSASLCredentials)
-  {
-    this.serverSASLCredentials = serverSASLCredentials;
-  }
-
-
+  public abstract void setServerSASLCredentials(
+      ASN1OctetString serverSASLCredentials);
 
   /**
    * Retrieves the user entry associated with the SASL authentication attempt.
@@ -636,12 +171,7 @@
    *          <CODE>null</CODE> if it was not a SASL authentication or the SASL
    *          processing was not able to map the request to a user.
    */
-  public final Entry getSASLAuthUserEntry()
-  {
-    return saslAuthUserEntry;
-  }
-
-
+  public abstract Entry getSASLAuthUserEntry();
 
   /**
    * Specifies the user entry associated with the SASL authentication attempt.
@@ -652,12 +182,7 @@
    * @param  saslAuthUserEntry  The user entry associated with the SASL
    *                            authentication attempt.
    */
-  public final void setSASLAuthUserEntry(Entry saslAuthUserEntry)
-  {
-    this.saslAuthUserEntry = saslAuthUserEntry;
-  }
-
-
+  public abstract void setSASLAuthUserEntry(Entry saslAuthUserEntry);
 
   /**
    * Retrieves a human-readable message providing the reason that the
@@ -666,12 +191,7 @@
    * @return  A human-readable message providing the reason that the
    *          authentication failed, or <CODE>null</CODE> if none is available.
    */
-  public final String getAuthFailureReason()
-  {
-    return authFailureReason;
-  }
-
-
+  public abstract String getAuthFailureReason();
 
   /**
    * Retrieves the unique identifier for the authentication failure reason, if
@@ -680,12 +200,7 @@
    * @return  The unique identifier for the authentication failure reason, or
    *          zero if none is available.
    */
-  public final int getAuthFailureID()
-  {
-    return authFailureID;
-  }
-
-
+  public abstract int getAuthFailureID();
 
   /**
    * Specifies the reason that the authentication failed.
@@ -695,21 +210,7 @@
    * @param  reason  A human-readable message providing the reason that the
    *                 authentication failed.
    */
-  public final void setAuthFailureReason(int id, String reason)
-  {
-    if (id < 0)
-    {
-      authFailureID = 0;
-    }
-    else
-    {
-      authFailureID = id;
-    }
-
-    authFailureReason = reason;
-  }
-
-
+  public abstract void setAuthFailureReason(int id, String reason);
 
   /**
    * Retrieves the user entry DN for this bind operation.  It will only be
@@ -720,12 +221,7 @@
    *          the bind processing has not progressed far enough to identify the
    *          user or if the user DN could not be determined.
    */
-  public final DN getUserEntryDN()
-  {
-    return userEntryDN;
-  }
-
-
+  public abstract DN getUserEntryDN();
 
   /**
    * Retrieves the authentication info that resulted from processing this bind
@@ -734,12 +230,7 @@
    * @return  The authentication info that resulted from processing this bind
    *          operation.
    */
-  public final AuthenticationInfo getAuthenticationInfo()
-  {
-    return authInfo;
-  }
-
-
+  public abstract AuthenticationInfo getAuthenticationInfo();
 
   /**
    * Specifies the authentication info that resulted from processing this bind
@@ -749,1674 +240,17 @@
    * @param  authInfo  The authentication info that resulted from processing
    *                   this bind operation.
    */
-  public final void setAuthenticationInfo(AuthenticationInfo authInfo)
-  {
-    this.authInfo = authInfo;
-  }
-
-
+  public abstract void setAuthenticationInfo(AuthenticationInfo authInfo);
 
   /**
-   * {@inheritDoc}
+   * Set the user entry DN for this bind operation.
+   *
+   * @param  userEntryDN  The user entry DN for this bind operation, or
+   *                      <CODE>null</CODE> if the bind processing has not
+   *                      progressed far enough to identify the user or if
+   *                      the user DN could not be determined.
    */
-  @Override()
-  public final long getProcessingStartTime()
-  {
-    return processingStartTime;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final long getProcessingStopTime()
-  {
-    return processingStopTime;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final long getProcessingTime()
-  {
-    return (processingStopTime - processingStartTime);
-  }
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final OperationType getOperationType()
-  {
-    // Note that no debugging will be done in this method because it is a likely
-    // candidate for being called by the logging subsystem.
-
-    return OperationType.BIND;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final void disconnectClient(DisconnectReason disconnectReason,
-                                     boolean sendNotification, String message,
-                                     int messageID)
-  {
-    // Since bind operations can't be cancelled, we don't need to do anything
-    // but forward the request on to the client connection.
-    clientConnection.disconnect(disconnectReason, sendNotification, message,
-                                messageID);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final String[][] getRequestLogElements()
-  {
-    // Note that no debugging will be done in this method because it is a likely
-    // candidate for being called by the logging subsystem.
-
-    if (authType == AuthenticationType.SASL)
-    {
-      return new String[][]
-      {
-        new String[] { LOG_ELEMENT_BIND_DN, String.valueOf(rawBindDN) },
-        new String[] { LOG_ELEMENT_AUTH_TYPE, authType.toString() },
-        new String[] { LOG_ELEMENT_SASL_MECHANISM, saslMechanism }
-      };
-    }
-    else
-    {
-      return new String[][]
-      {
-        new String[] { LOG_ELEMENT_BIND_DN, String.valueOf(rawBindDN) },
-        new String[] { LOG_ELEMENT_AUTH_TYPE, authType.toString() }
-      };
-    }
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final String[][] getResponseLogElements()
-  {
-    // Note that no debugging will be done in this method because it is a likely
-    // candidate for being called by the logging subsystem.
-
-    String resultCode = String.valueOf(getResultCode().getIntValue());
-
-    String errorMessage;
-    StringBuilder errorMessageBuffer = getErrorMessage();
-    if (errorMessageBuffer == null)
-    {
-      errorMessage = null;
-    }
-    else
-    {
-      errorMessage = errorMessageBuffer.toString();
-    }
-
-    String matchedDNStr;
-    DN matchedDN = getMatchedDN();
-    if (matchedDN == null)
-    {
-      matchedDNStr = null;
-    }
-    else
-    {
-      matchedDNStr = matchedDN.toString();
-    }
-
-    String referrals;
-    List<String> referralURLs = getReferralURLs();
-    if ((referralURLs == null) || referralURLs.isEmpty())
-    {
-      referrals = null;
-    }
-    else
-    {
-      StringBuilder buffer = new StringBuilder();
-      Iterator<String> iterator = referralURLs.iterator();
-      buffer.append(iterator.next());
-
-      while (iterator.hasNext())
-      {
-        buffer.append(", ");
-        buffer.append(iterator.next());
-      }
-
-      referrals = buffer.toString();
-    }
-
-    String processingTime =
-         String.valueOf(processingStopTime - processingStartTime);
-
-    return new String[][]
-    {
-      new String[] { LOG_ELEMENT_RESULT_CODE, resultCode },
-      new String[] { LOG_ELEMENT_ERROR_MESSAGE, errorMessage },
-      new String[] { LOG_ELEMENT_MATCHED_DN, matchedDNStr },
-      new String[] { LOG_ELEMENT_REFERRAL_URLS, referrals },
-      new String[] { LOG_ELEMENT_PROCESSING_TIME, processingTime }
-    };
-  }
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final List<Control> getResponseControls()
-  {
-    return responseControls;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final void addResponseControl(Control control)
-  {
-    responseControls.add(control);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final void removeResponseControl(Control control)
-  {
-    responseControls.remove(control);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final void run()
-  {
-    // Start the processing timer and initially set the result to indicate that
-    // the result is unknown.
-    processingStartTime = System.currentTimeMillis();
-    setResultCode(ResultCode.UNDEFINED);
-    boolean returnAuthzID    = false;
-    int     sizeLimit        = DirectoryServer.getSizeLimit();
-    int     timeLimit        = DirectoryServer.getTimeLimit();
-    int     lookthroughLimit = DirectoryServer.getLookthroughLimit();
-
-
-    // Set a flag to indicate that a bind operation is in progress.  This should
-    // ensure that no new operations will be accepted for this client until the
-    // bind is complete.
-    clientConnection.setBindInProgress(true);
-
-
-    // Wipe out any existing authentication for the client connection and create
-    // a placeholder that will be used if the bind is successful.
-    clientConnection.setUnauthenticated();
-    authInfo = null;
-
-
-    // Abandon any operations that may be in progress for the client.
-    String cancelReason = getMessage(MSGID_CANCELED_BY_BIND_REQUEST);
-    CancelRequest cancelRequest = new CancelRequest(true, cancelReason);
-    clientConnection.cancelAllOperationsExcept(cancelRequest, getMessageID());
-
-
-    // Get the plugin config manager that will be used for invoking plugins.
-    PluginConfigManager pluginConfigManager =
-         DirectoryServer.getPluginConfigManager();
-    boolean skipPostOperation = false;
-
-
-    // Create a labeled block of code that we can break out of if a problem is
-    // detected.
-bindProcessing:
-    {
-      // Invoke the pre-parse bind plugins.
-      PreParsePluginResult preParseResult =
-           pluginConfigManager.invokePreParseBindPlugins(this);
-      if (preParseResult.connectionTerminated())
-      {
-        // There's no point in continuing with anything.  Log the request and
-        // result and return.
-        setResultCode(ResultCode.CANCELED);
-
-        int msgID = MSGID_CANCELED_BY_PREPARSE_DISCONNECT;
-        appendErrorMessage(getMessage(msgID));
-
-        processingStopTime = System.currentTimeMillis();
-
-        logBindRequest(this);
-        logBindResponse(this);
-        pluginConfigManager.invokePostResponseBindPlugins(this);
-        return;
-      }
-      else if (preParseResult.sendResponseImmediately())
-      {
-        skipPostOperation = true;
-        logBindRequest(this);
-        break bindProcessing;
-      }
-      else if (preParseResult.skipCoreProcessing())
-      {
-        skipPostOperation = false;
-        break bindProcessing;
-      }
-
-
-      // Log the bind request message.
-      logBindRequest(this);
-
-
-      // Process the bind DN to convert it from the raw form as provided by the
-      // client into the form required for the rest of the bind processing.
-      try
-      {
-        if (bindDN == null)
-        {
-          bindDN = DN.decode(rawBindDN);
-        }
-      }
-      catch (DirectoryException de)
-      {
-        if (debugEnabled())
-        {
-          TRACER.debugCaught(DebugLogLevel.ERROR, de);
-        }
-
-        setResultCode(ResultCode.INVALID_CREDENTIALS);
-        setAuthFailureReason(de.getMessageID(), de.getErrorMessage());
-        break bindProcessing;
-      }
-
-      // Check to see if the client has permission to perform the
-      // bind.
-
-      // FIXME: for now assume that this will check all permission
-      // pertinent to the operation. This includes any controls
-      // specified.
-      if (AccessControlConfigManager.getInstance()
-          .getAccessControlHandler().isAllowed(this) == false) {
-        setResultCode(ResultCode.INVALID_CREDENTIALS);
-
-        int    msgID   = MSGID_BIND_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
-        String message = getMessage(msgID, String.valueOf(bindDN));
-        setAuthFailureReason(msgID, message);
-
-        skipPostOperation = true;
-        break bindProcessing;
-      }
-
-      // Check to see if there are any controls in the request.  If so, then see
-      // if there is any special processing required.
-      List<Control> requestControls = getRequestControls();
-      if ((requestControls != null) && (! requestControls.isEmpty()))
-      {
-        for (int i=0; i < requestControls.size(); i++)
-        {
-          Control c   = requestControls.get(i);
-          String  oid = c.getOID();
-
-          if (oid.equals(OID_AUTHZID_REQUEST))
-          {
-            returnAuthzID = true;
-          }
-          else if (oid.equals(OID_PASSWORD_POLICY_CONTROL))
-          {
-            pwPolicyControlRequested = true;
-          }
-
-          // NYI -- Add support for additional controls.
-          else if (c.isCritical())
-          {
-            setResultCode(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION);
-
-            int msgID = MSGID_BIND_UNSUPPORTED_CRITICAL_CONTROL;
-            appendErrorMessage(getMessage(msgID, String.valueOf(oid)));
-
-            break bindProcessing;
-          }
-        }
-      }
-
-
-      // Check to see if this is a simple bind or a SASL bind and process
-      // accordingly.
-      switch (authType)
-      {
-        case SIMPLE:
-          // See if this is an anonymous bind.  If so, then determine whether
-          // to allow it.
-          if ((simplePassword == null) || (simplePassword.value().length == 0))
-          {
-            // If the server is in lockdown mode, then fail.
-            if (DirectoryServer.lockdownMode())
-            {
-              setResultCode(ResultCode.INVALID_CREDENTIALS);
-
-              int msgID = MSGID_BIND_REJECTED_LOCKDOWN_MODE;
-              setAuthFailureReason(msgID, getMessage(msgID));
-
-              processingStopTime = System.currentTimeMillis();
-              logBindResponse(this);
-              break bindProcessing;
-            }
-
-            // If there is a bind DN, then see whether that is acceptable.
-            if (DirectoryServer.bindWithDNRequiresPassword() &&
-                ((bindDN != null) && (! bindDN.isNullDN())))
-            {
-              setResultCode(ResultCode.UNWILLING_TO_PERFORM);
-
-              int    msgID   = MSGID_BIND_DN_BUT_NO_PASSWORD;
-              String message = getMessage(msgID);
-              setAuthFailureReason(msgID, message);
-              break bindProcessing;
-            }
-
-
-            // Invoke the pre-operation bind plugins.
-            PreOperationPluginResult preOpResult =
-                 pluginConfigManager.invokePreOperationBindPlugins(this);
-            if (preOpResult.connectionTerminated())
-            {
-              // There's no point in continuing with anything.  Log the result
-              // and return.
-              setResultCode(ResultCode.CANCELED);
-
-              int msgID = MSGID_CANCELED_BY_PREOP_DISCONNECT;
-              appendErrorMessage(getMessage(msgID));
-
-              processingStopTime = System.currentTimeMillis();
-
-              logBindResponse(this);
-              pluginConfigManager.invokePostResponseBindPlugins(this);
-              return;
-            }
-            else if (preOpResult.sendResponseImmediately())
-            {
-              skipPostOperation = true;
-              break bindProcessing;
-            }
-            else if (preOpResult.skipCoreProcessing())
-            {
-              skipPostOperation = false;
-              break bindProcessing;
-            }
-
-            setResultCode(ResultCode.SUCCESS);
-            authInfo = new AuthenticationInfo();
-            break bindProcessing;
-          }
-
-
-          // See if the bind DN is actually one of the alternate root DNs
-          // defined in the server.  If so, then replace it with the actual DN
-          // for that user.
-          DN actualRootDN = DirectoryServer.getActualRootBindDN(bindDN);
-          if (actualRootDN != null)
-          {
-            bindDN = actualRootDN;
-          }
-
-
-          // Get the user entry based on the bind DN.  If it does not exist,
-          // then fail.
-          Lock userLock = null;
-          for (int i=0; i < 3; i++)
-          {
-            userLock = LockManager.lockRead(bindDN);
-            if (userLock != null)
-            {
-              break;
-            }
-          }
-
-          if (userLock == null)
-          {
-            int    msgID   = MSGID_BIND_OPERATION_CANNOT_LOCK_USER;
-            String message = getMessage(msgID, String.valueOf(bindDN));
-
-            setResultCode(DirectoryServer.getServerErrorResultCode());
-            setAuthFailureReason(msgID, message);
-            break bindProcessing;
-          }
-
-          try
-          {
-            Entry userEntry;
-            try
-            {
-              userEntry = DirectoryServer.getEntry(bindDN);
-            }
-            catch (DirectoryException de)
-            {
-              if (debugEnabled())
-              {
-                TRACER.debugCaught(DebugLogLevel.ERROR, de);
-              }
-
-              setResultCode(ResultCode.INVALID_CREDENTIALS);
-              setAuthFailureReason(de.getMessageID(),
-                                   de.getErrorMessage());
-
-              userEntry = null;
-              break bindProcessing;
-            }
-
-            if (userEntry == null)
-            {
-
-              int    msgID   = MSGID_BIND_OPERATION_UNKNOWN_USER;
-              String message = getMessage(msgID, String.valueOf(bindDN));
-
-              setResultCode(ResultCode.INVALID_CREDENTIALS);
-              setAuthFailureReason(msgID, message);
-              break bindProcessing;
-            }
-            else
-            {
-              userEntryDN = userEntry.getDN();
-            }
-
-
-            // Check to see if the user has a password.  If not, then fail.
-            // FIXME -- We need to have a way to enable/disable debugging.
-            pwPolicyState = new PasswordPolicyState(userEntry, false, false);
-            AttributeType pwType
-                 = pwPolicyState.getPolicy().getPasswordAttribute();
-
-            List<Attribute> pwAttr = userEntry.getAttribute(pwType);
-            if ((pwAttr == null) || (pwAttr.isEmpty()))
-            {
-              int    msgID   = MSGID_BIND_OPERATION_NO_PASSWORD;
-              String message = getMessage(msgID, String.valueOf(bindDN));
-
-              setResultCode(ResultCode.INVALID_CREDENTIALS);
-              setAuthFailureReason(msgID, message);
-              break bindProcessing;
-            }
-
-
-            // Check to see if the authentication must be done in a secure
-            // manner.  If so, then the client connection must be secure.
-            if (pwPolicyState.getPolicy().requireSecureAuthentication() &&
-                (! clientConnection.isSecure()))
-            {
-              int    msgID   = MSGID_BIND_OPERATION_INSECURE_SIMPLE_BIND;
-              String message = getMessage(msgID, String.valueOf(bindDN));
-
-              setResultCode(ResultCode.INVALID_CREDENTIALS);
-              setAuthFailureReason(msgID, message);
-              break bindProcessing;
-            }
-
-
-            // Check to see if the user is administratively disabled or locked.
-            if (pwPolicyState.isDisabled())
-            {
-              int    msgID   = MSGID_BIND_OPERATION_ACCOUNT_DISABLED;
-              String message = getMessage(msgID, String.valueOf(bindDN));
-
-              setResultCode(ResultCode.INVALID_CREDENTIALS);
-              setAuthFailureReason(msgID, message);
-              break bindProcessing;
-            }
-            else if (pwPolicyState.isAccountExpired())
-            {
-              int    msgID   = MSGID_BIND_OPERATION_ACCOUNT_EXPIRED;
-              String message = getMessage(msgID, String.valueOf(bindDN));
-
-              setResultCode(ResultCode.INVALID_CREDENTIALS);
-              setAuthFailureReason(msgID, message);
-
-              pwPolicyState.generateAccountStatusNotification(
-                   AccountStatusNotificationType.ACCOUNT_EXPIRED, bindDN, msgID,
-                   message);
-
-              break bindProcessing;
-            }
-            else if (pwPolicyState.lockedDueToFailures())
-            {
-              int    msgID   = MSGID_BIND_OPERATION_ACCOUNT_FAILURE_LOCKED;
-              String message = getMessage(msgID, String.valueOf(bindDN));
-
-              if (pwPolicyErrorType == null)
-              {
-                pwPolicyErrorType = PasswordPolicyErrorType.ACCOUNT_LOCKED;
-              }
-
-              setResultCode(ResultCode.INVALID_CREDENTIALS);
-              setAuthFailureReason(msgID, message);
-              break bindProcessing;
-            }
-            else if (pwPolicyState.lockedDueToMaximumResetAge())
-            {
-              int    msgID   = MSGID_BIND_OPERATION_ACCOUNT_RESET_LOCKED;
-              String message = getMessage(msgID, String.valueOf(bindDN));
-
-              if (pwPolicyErrorType == null)
-              {
-                pwPolicyErrorType = PasswordPolicyErrorType.ACCOUNT_LOCKED;
-              }
-
-              setResultCode(ResultCode.INVALID_CREDENTIALS);
-              setAuthFailureReason(msgID, message);
-
-              pwPolicyState.generateAccountStatusNotification(
-                   AccountStatusNotificationType.ACCOUNT_RESET_LOCKED, bindDN,
-                   msgID, message);
-
-              break bindProcessing;
-            }
-            else if (pwPolicyState.lockedDueToIdleInterval())
-            {
-              int    msgID   = MSGID_BIND_OPERATION_ACCOUNT_IDLE_LOCKED;
-              String message = getMessage(msgID, String.valueOf(bindDN));
-
-              if (pwPolicyErrorType == null)
-              {
-                pwPolicyErrorType = PasswordPolicyErrorType.ACCOUNT_LOCKED;
-              }
-
-              setResultCode(ResultCode.INVALID_CREDENTIALS);
-              setAuthFailureReason(msgID, message);
-
-              pwPolicyState.generateAccountStatusNotification(
-                   AccountStatusNotificationType.ACCOUNT_IDLE_LOCKED, bindDN,
-                   msgID, message);
-
-              break bindProcessing;
-            }
-
-
-            // 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
-                   = pwPolicyState.getPolicy().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
-                {
-                  int    msgID   = MSGID_BIND_OPERATION_PASSWORD_EXPIRED;
-                  String message = getMessage(msgID, String.valueOf(bindDN));
-
-                  setResultCode(ResultCode.INVALID_CREDENTIALS);
-                  setAuthFailureReason(msgID, message);
-
-                  pwPolicyState.generateAccountStatusNotification(
-                       AccountStatusNotificationType.PASSWORD_EXPIRED, bindDN,
-                       msgID, message);
-
-                  break bindProcessing;
-                }
-              }
-              else
-              {
-                int    msgID   = MSGID_BIND_OPERATION_PASSWORD_EXPIRED;
-                String message = getMessage(msgID, String.valueOf(bindDN));
-
-                setResultCode(ResultCode.INVALID_CREDENTIALS);
-                setAuthFailureReason(msgID, message);
-
-                pwPolicyState.generateAccountStatusNotification(
-                     AccountStatusNotificationType.PASSWORD_EXPIRED, bindDN,
-                     msgID, message);
-
-                break bindProcessing;
-              }
-            }
-            else if (pwPolicyState.shouldWarn())
-            {
-              int numSeconds = pwPolicyState.getSecondsUntilExpiration();
-              String timeToExpiration = secondsToTimeString(numSeconds);
-
-              int msgID = MSGID_BIND_PASSWORD_EXPIRING;
-              String message = getMessage(msgID, timeToExpiration);
-              appendErrorMessage(message);
-
-              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;
-              }
-            }
-
-
-            // Invoke the pre-operation bind plugins.
-            PreOperationPluginResult preOpResult =
-                 pluginConfigManager.invokePreOperationBindPlugins(this);
-            if (preOpResult.connectionTerminated())
-            {
-              // There's no point in continuing with anything.  Log the result
-              // and return.
-              setResultCode(ResultCode.CANCELED);
-
-              int msgID = MSGID_CANCELED_BY_PREOP_DISCONNECT;
-              appendErrorMessage(getMessage(msgID));
-
-              processingStopTime = System.currentTimeMillis();
-
-              logBindResponse(this);
-              pluginConfigManager.invokePostResponseBindPlugins(this);
-              return;
-            }
-            else if (preOpResult.sendResponseImmediately())
-            {
-              skipPostOperation = true;
-              break bindProcessing;
-            }
-            else if (preOpResult.skipCoreProcessing())
-            {
-              skipPostOperation = false;
-              break bindProcessing;
-            }
-
-
-            // Determine whether the provided password matches any of the stored
-            // passwords for the user.
-            if (pwPolicyState.passwordMatches(simplePassword))
-            {
-              setResultCode(ResultCode.SUCCESS);
-
-              boolean isRoot = DirectoryServer.isRootDN(userEntry.getDN());
-              if (DirectoryServer.lockdownMode() && (! isRoot))
-              {
-                setResultCode(ResultCode.INVALID_CREDENTIALS);
-
-                int msgID = MSGID_BIND_REJECTED_LOCKDOWN_MODE;
-                setAuthFailureReason(msgID, getMessage(msgID));
-
-                break bindProcessing;
-              }
-
-              authInfo = new AuthenticationInfo(userEntry, simplePassword,
-                                                isRoot);
-
-
-              // See if the user's entry contains a custom size limit.
-              AttributeType attrType =
-                   DirectoryServer.getAttributeType(OP_ATTR_USER_SIZE_LIMIT,
-                                                 true);
-              List<Attribute> attrList = userEntry.getAttribute(attrType);
-              if ((attrList != null) && (attrList.size() == 1))
-              {
-                Attribute a = attrList.get(0);
-                LinkedHashSet<AttributeValue>  values = a.getValues();
-                Iterator<AttributeValue> iterator = values.iterator();
-                if (iterator.hasNext())
-                {
-                  AttributeValue v = iterator.next();
-                  if (iterator.hasNext())
-                  {
-                    int msgID = MSGID_BIND_MULTIPLE_USER_SIZE_LIMITS;
-                    String message =
-                         getMessage(msgID, String.valueOf(userEntry.getDN()));
-                    logError(ErrorLogCategory.CORE_SERVER,
-                             ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-                  }
-                  else
-                  {
-                    try
-                    {
-                      sizeLimit = Integer.parseInt(v.getStringValue());
-                    }
-                    catch (Exception e)
-                    {
-                      if (debugEnabled())
-                      {
-                        TRACER.debugCaught(DebugLogLevel.ERROR, e);
-                      }
-
-                      int msgID = MSGID_BIND_CANNOT_PROCESS_USER_SIZE_LIMIT;
-                      String message =
-                           getMessage(msgID, v.getStringValue(),
-                                      String.valueOf(userEntry.getDN()));
-                      logError(ErrorLogCategory.CORE_SERVER,
-                               ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-                    }
-                  }
-                }
-              }
-
-
-              // See if the user's entry contains a custom time limit.
-              attrType =
-                   DirectoryServer.getAttributeType(OP_ATTR_USER_TIME_LIMIT,
-                                                 true);
-              attrList = userEntry.getAttribute(attrType);
-              if ((attrList != null) && (attrList.size() == 1))
-              {
-                Attribute a = attrList.get(0);
-                LinkedHashSet<AttributeValue>  values = a.getValues();
-                Iterator<AttributeValue> iterator = values.iterator();
-                if (iterator.hasNext())
-                {
-                  AttributeValue v = iterator.next();
-                  if (iterator.hasNext())
-                  {
-                    int msgID = MSGID_BIND_MULTIPLE_USER_TIME_LIMITS;
-                    String message =
-                         getMessage(msgID, String.valueOf(userEntry.getDN()));
-                    logError(ErrorLogCategory.CORE_SERVER,
-                             ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-                  }
-                  else
-                  {
-                    try
-                    {
-                      timeLimit = Integer.parseInt(v.getStringValue());
-                    }
-                    catch (Exception e)
-                    {
-                      if (debugEnabled())
-                      {
-                        TRACER.debugCaught(DebugLogLevel.ERROR, e);
-                      }
-
-                      int msgID = MSGID_BIND_CANNOT_PROCESS_USER_TIME_LIMIT;
-                      String message =
-                           getMessage(msgID, v.getStringValue(),
-                                      String.valueOf(userEntry.getDN()));
-                      logError(ErrorLogCategory.CORE_SERVER,
-                               ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-                    }
-                  }
-                }
-              }
-
-
-              // See if the user's entry contains a custom lookthrough limit.
-              attrType =
-                   DirectoryServer.getAttributeType(
-                       OP_ATTR_USER_LOOKTHROUGH_LIMIT, true);
-              attrList = userEntry.getAttribute(attrType);
-              if ((attrList != null) && (attrList.size() == 1))
-              {
-                Attribute a = attrList.get(0);
-                LinkedHashSet<AttributeValue>  values = a.getValues();
-                Iterator<AttributeValue> iterator = values.iterator();
-                if (iterator.hasNext())
-                {
-                  AttributeValue v = iterator.next();
-                  if (iterator.hasNext())
-                  {
-                    int msgID = MSGID_BIND_MULTIPLE_USER_LOOKTHROUGH_LIMITS;
-                    String message =
-                         getMessage(msgID, String.valueOf(userEntry.getDN()));
-                    logError(ErrorLogCategory.CORE_SERVER,
-                             ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-                  }
-                  else
-                  {
-                    try
-                    {
-                      lookthroughLimit = Integer.parseInt(v.getStringValue());
-                    }
-                    catch (Exception e)
-                    {
-                      if (debugEnabled())
-                      {
-                        TRACER.debugCaught(DebugLogLevel.ERROR, e);
-                      }
-
-                      int msgID =
-                          MSGID_BIND_CANNOT_PROCESS_USER_LOOKTHROUGH_LIMIT;
-                      String message =
-                           getMessage(msgID, v.getStringValue(),
-                                      String.valueOf(userEntry.getDN()));
-                      logError(ErrorLogCategory.CORE_SERVER,
-                               ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-                    }
-                  }
-                }
-              }
-
-
-              pwPolicyState.handleDeprecatedStorageSchemes(simplePassword);
-              pwPolicyState.clearFailureLockout();
-
-              if (isFirstWarning)
-              {
-                pwPolicyState.setWarnedTime();
-
-                int numSeconds = pwPolicyState.getSecondsUntilExpiration();
-                String timeToExpiration = secondsToTimeString(numSeconds);
-
-                int msgID = MSGID_BIND_PASSWORD_EXPIRING;
-                String message = getMessage(msgID, timeToExpiration);
-
-                pwPolicyState.generateAccountStatusNotification(
-                     AccountStatusNotificationType.PASSWORD_EXPIRING, bindDN,
-                     msgID, message);
-              }
-
-              if (isGraceLogin)
-              {
-                pwPolicyState.updateGraceLoginTimes();
-              }
-
-              pwPolicyState.setLastLoginTime();
-            }
-            else
-            {
-              int    msgID   = MSGID_BIND_OPERATION_WRONG_PASSWORD;
-              String message = getMessage(msgID);
-
-              setResultCode(ResultCode.INVALID_CREDENTIALS);
-              setAuthFailureReason(msgID, message);
-
-              if (pwPolicyState.getPolicy().getLockoutFailureCount() > 0)
-              {
-                pwPolicyState.updateAuthFailureTimes();
-                if (pwPolicyState.lockedDueToFailures())
-                {
-                  AccountStatusNotificationType notificationType;
-
-                  int lockoutDuration = pwPolicyState.getSecondsUntilUnlock();
-                  if (lockoutDuration > -1)
-                  {
-                    notificationType = AccountStatusNotificationType.
-                                            ACCOUNT_TEMPORARILY_LOCKED;
-                    msgID   = MSGID_BIND_ACCOUNT_TEMPORARILY_LOCKED;
-                    message = getMessage(msgID,
-                                         secondsToTimeString(lockoutDuration));
-                  }
-                  else
-                  {
-                    notificationType = AccountStatusNotificationType.
-                                            ACCOUNT_PERMANENTLY_LOCKED;
-                    msgID   = MSGID_BIND_ACCOUNT_PERMANENTLY_LOCKED;
-                    message = getMessage(msgID);
-                  }
-
-                  pwPolicyState.generateAccountStatusNotification(
-                       notificationType, userEntryDN, msgID, message);
-                }
-              }
-            }
-          }
-          catch (Exception e)
-          {
-            if (debugEnabled())
-            {
-              TRACER.debugCaught(DebugLogLevel.ERROR, e);
-            }
-
-            int    msgID   = MSGID_BIND_OPERATION_PASSWORD_VALIDATION_EXCEPTION;
-            String message = getMessage(msgID, getExceptionMessage(e));
-
-            setResultCode(DirectoryServer.getServerErrorResultCode());
-            setAuthFailureReason(msgID, message);
-            break bindProcessing;
-          }
-          finally
-          {
-            // No matter what, make sure to unlock the user's entry.
-            LockManager.unlock(bindDN, userLock);
-          }
-
-          break;
-
-
-        case SASL:
-          // Get the appropriate authentication handler for this request based
-          // on the SASL mechanism.  If there is none, then fail.
-          SASLMechanismHandler saslHandler =
-               DirectoryServer.getSASLMechanismHandler(saslMechanism);
-          if (saslHandler == null)
-          {
-            setResultCode(ResultCode.AUTH_METHOD_NOT_SUPPORTED);
-
-            int    msgID   = MSGID_BIND_OPERATION_UNKNOWN_SASL_MECHANISM;
-            String message = getMessage(msgID, saslMechanism);
-
-            appendErrorMessage(message);
-            setAuthFailureReason(msgID, message);
-            break bindProcessing;
-          }
-
-
-          // Check to see if the client has sufficient permission to perform the
-          // bind.
-          // NYI
-
-
-          // Invoke the pre-operation bind plugins.
-          PreOperationPluginResult preOpResult =
-               pluginConfigManager.invokePreOperationBindPlugins(this);
-          if (preOpResult.connectionTerminated())
-          {
-            // There's no point in continuing with anything.  Log the result
-            // and return.
-            setResultCode(ResultCode.CANCELED);
-
-            int msgID = MSGID_CANCELED_BY_PREOP_DISCONNECT;
-            appendErrorMessage(getMessage(msgID));
-
-            processingStopTime = System.currentTimeMillis();
-
-            logBindResponse(this);
-            pluginConfigManager.invokePostResponseBindPlugins(this);
-            return;
-          }
-          else if (preOpResult.sendResponseImmediately())
-          {
-            skipPostOperation = true;
-            break bindProcessing;
-          }
-          else if (preOpResult.skipCoreProcessing())
-          {
-            skipPostOperation = false;
-            break bindProcessing;
-          }
-
-
-          // Actually process the SASL bind.
-          saslHandler.processSASLBind(this);
-
-
-          // If the server is operating in lockdown mode, then we will need to
-          // ensure that the authentication was successful and performed as a
-          // root user to continue.
-          if (DirectoryServer.lockdownMode())
-          {
-            ResultCode resultCode = getResultCode();
-            if (resultCode != ResultCode.SASL_BIND_IN_PROGRESS)
-            {
-              if ((resultCode != ResultCode.SUCCESS) ||
-                  (saslAuthUserEntry == null) ||
-                  (! DirectoryServer.isRootDN(saslAuthUserEntry.getDN())))
-              {
-                setResultCode(ResultCode.INVALID_CREDENTIALS);
-
-                int msgID = MSGID_BIND_REJECTED_LOCKDOWN_MODE;
-                setAuthFailureReason(msgID, getMessage(msgID));
-
-                break bindProcessing;
-              }
-            }
-          }
-
-
-          // Create the password policy state object.
-          String userDNString;
-          if (saslAuthUserEntry == null)
-          {
-            pwPolicyState = null;
-            userDNString  = null;
-          }
-          else
-          {
-            try
-            {
-              // FIXME -- Need to have a way to enable debugging.
-              pwPolicyState = new PasswordPolicyState(saslAuthUserEntry, false,
-                                                      false);
-              userEntryDN = saslAuthUserEntry.getDN();
-              userDNString = String.valueOf(userEntryDN);
-            }
-            catch (DirectoryException de)
-            {
-              if (debugEnabled())
-              {
-                TRACER.debugCaught(DebugLogLevel.ERROR, de);
-              }
-
-              setResponseData(de);
-              break bindProcessing;
-            }
-          }
-
-
-          // Perform password policy checks that will need to be completed
-          // regardless of whether the authentication was successful.
-          if (pwPolicyState != null)
-          {
-            if (pwPolicyState.isDisabled())
-            {
-              setResultCode(ResultCode.INVALID_CREDENTIALS);
-
-              int    msgID   = MSGID_BIND_OPERATION_ACCOUNT_DISABLED;
-              String message = getMessage(msgID, userDNString);
-              setAuthFailureReason(msgID, message);
-              break bindProcessing;
-            }
-            else if (pwPolicyState.isAccountExpired())
-            {
-              setResultCode(ResultCode.INVALID_CREDENTIALS);
-
-              int    msgID   = MSGID_BIND_OPERATION_ACCOUNT_EXPIRED;
-              String message = getMessage(msgID, userDNString);
-              setAuthFailureReason(msgID, message);
-
-              pwPolicyState.generateAccountStatusNotification(
-                   AccountStatusNotificationType.ACCOUNT_EXPIRED, bindDN, msgID,
-                   message);
-
-              break bindProcessing;
-            }
-
-            if (pwPolicyState.getPolicy().requireSecureAuthentication() &&
-                (! clientConnection.isSecure()) &&
-                (! saslHandler.isSecure(saslMechanism)))
-            {
-              setResultCode(ResultCode.INVALID_CREDENTIALS);
-
-              int    msgID   = MSGID_BIND_OPERATION_INSECURE_SASL_BIND;
-              String message = getMessage(msgID, saslMechanism, userDNString);
-              setAuthFailureReason(msgID, message);
-              break bindProcessing;
-            }
-
-            if (pwPolicyState.lockedDueToFailures())
-            {
-              setResultCode(ResultCode.INVALID_CREDENTIALS);
-
-              if (pwPolicyErrorType == null)
-              {
-                pwPolicyErrorType = PasswordPolicyErrorType.ACCOUNT_LOCKED;
-              }
-
-              int    msgID   = MSGID_BIND_OPERATION_ACCOUNT_FAILURE_LOCKED;
-              String message = getMessage(msgID, userDNString);
-              setAuthFailureReason(msgID, message);
-              break bindProcessing;
-            }
-
-            if (pwPolicyState.lockedDueToIdleInterval())
-            {
-              setResultCode(ResultCode.INVALID_CREDENTIALS);
-
-              if (pwPolicyErrorType == null)
-              {
-                pwPolicyErrorType = PasswordPolicyErrorType.ACCOUNT_LOCKED;
-              }
-
-              int    msgID   = MSGID_BIND_OPERATION_ACCOUNT_IDLE_LOCKED;
-              String message = getMessage(msgID, userDNString);
-              setAuthFailureReason(msgID, message);
-
-              pwPolicyState.generateAccountStatusNotification(
-                   AccountStatusNotificationType.ACCOUNT_IDLE_LOCKED, bindDN,
-                   msgID, message);
-
-              break bindProcessing;
-            }
-
-
-            if (saslHandler.isPasswordBased(saslMechanism))
-            {
-              if (pwPolicyState.lockedDueToMaximumResetAge())
-              {
-                setResultCode(ResultCode.INVALID_CREDENTIALS);
-
-                if (pwPolicyErrorType == null)
-                {
-                  pwPolicyErrorType = PasswordPolicyErrorType.ACCOUNT_LOCKED;
-                }
-
-                int    msgID   = MSGID_BIND_OPERATION_ACCOUNT_RESET_LOCKED;
-                String message = getMessage(msgID, userDNString);
-                setAuthFailureReason(msgID, message);
-
-                pwPolicyState.generateAccountStatusNotification(
-                     AccountStatusNotificationType.ACCOUNT_RESET_LOCKED, bindDN,
-                     msgID, message);
-
-                break bindProcessing;
-              }
-
-              if (pwPolicyState.isPasswordExpired())
-              {
-                if (pwPolicyErrorType == null)
-                {
-                  pwPolicyErrorType = PasswordPolicyErrorType.PASSWORD_EXPIRED;
-                }
-
-                int maxGraceLogins
-                     = pwPolicyState.getPolicy().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
-                  {
-                    int    msgID   = MSGID_BIND_OPERATION_PASSWORD_EXPIRED;
-                    String message = getMessage(msgID, String.valueOf(bindDN));
-
-                    setResultCode(ResultCode.INVALID_CREDENTIALS);
-                    setAuthFailureReason(msgID, message);
-
-                    pwPolicyState.generateAccountStatusNotification(
-                         AccountStatusNotificationType.PASSWORD_EXPIRED, bindDN,
-                         msgID, message);
-
-                    break bindProcessing;
-                  }
-                }
-                else
-                {
-                  int    msgID   = MSGID_BIND_OPERATION_PASSWORD_EXPIRED;
-                  String message = getMessage(msgID, String.valueOf(bindDN));
-
-                  setResultCode(ResultCode.INVALID_CREDENTIALS);
-                  setAuthFailureReason(msgID, message);
-
-                  pwPolicyState.generateAccountStatusNotification(
-                       AccountStatusNotificationType.PASSWORD_EXPIRED, bindDN,
-                       msgID, message);
-
-                  break bindProcessing;
-                }
-              }
-              else if (pwPolicyState.shouldWarn())
-              {
-                int numSeconds = pwPolicyState.getSecondsUntilExpiration();
-                String timeToExpiration = secondsToTimeString(numSeconds);
-
-                int    msgID   = MSGID_BIND_PASSWORD_EXPIRING;
-                String message = getMessage(msgID, timeToExpiration);
-                appendErrorMessage(message);
-
-                if (pwPolicyWarningType == null)
-                {
-                  pwPolicyWarningType =
-                       PasswordPolicyWarningType.TIME_BEFORE_EXPIRATION;
-                  pwPolicyWarningValue = numSeconds;
-                }
-
-                isFirstWarning = pwPolicyState.isFirstWarning();
-              }
-            }
-          }
-
-
-          // Determine whether the authentication was successful and perform
-          // any remaining password policy processing accordingly.  Also check
-          // for a custom size/time limit.
-          ResultCode resultCode = getResultCode();
-          if (resultCode == ResultCode.SUCCESS)
-          {
-            if (pwPolicyState != null)
-            {
-              if (saslHandler.isPasswordBased(saslMechanism) &&
-                  pwPolicyState.mustChangePassword())
-              {
-                mustChangePassword = true;
-              }
-
-              if (isFirstWarning)
-              {
-                pwPolicyState.setWarnedTime();
-
-                int numSeconds = pwPolicyState.getSecondsUntilExpiration();
-                String timeToExpiration = secondsToTimeString(numSeconds);
-
-                int msgID = MSGID_BIND_PASSWORD_EXPIRING;
-                String message = getMessage(msgID, timeToExpiration);
-
-                pwPolicyState.generateAccountStatusNotification(
-                     AccountStatusNotificationType.PASSWORD_EXPIRING, bindDN,
-                     msgID, message);
-              }
-
-              if (isGraceLogin)
-              {
-                pwPolicyState.updateGraceLoginTimes();
-              }
-
-              pwPolicyState.setLastLoginTime();
-
-
-              // See if the user's entry contains a custom size limit.
-              AttributeType attrType =
-                   DirectoryServer.getAttributeType(OP_ATTR_USER_SIZE_LIMIT,
-                                                 true);
-              List<Attribute> attrList =
-                   saslAuthUserEntry.getAttribute(attrType);
-              if ((attrList != null) && (attrList.size() == 1))
-              {
-                Attribute a = attrList.get(0);
-                LinkedHashSet<AttributeValue>  values = a.getValues();
-                Iterator<AttributeValue> iterator = values.iterator();
-                if (iterator.hasNext())
-                {
-                  AttributeValue v = iterator.next();
-                  if (iterator.hasNext())
-                  {
-                    int msgID = MSGID_BIND_MULTIPLE_USER_SIZE_LIMITS;
-                    String message = getMessage(msgID, userDNString);
-                    logError(ErrorLogCategory.CORE_SERVER,
-                             ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-                  }
-                  else
-                  {
-                    try
-                    {
-                      sizeLimit = Integer.parseInt(v.getStringValue());
-                    }
-                    catch (Exception e)
-                    {
-                      if (debugEnabled())
-                      {
-                        TRACER.debugCaught(DebugLogLevel.ERROR, e);
-                      }
-
-                      int msgID = MSGID_BIND_CANNOT_PROCESS_USER_SIZE_LIMIT;
-                      String message =
-                           getMessage(msgID, v.getStringValue(), userDNString);
-                      logError(ErrorLogCategory.CORE_SERVER,
-                               ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-                    }
-                  }
-                }
-              }
-
-
-              // See if the user's entry contains a custom time limit.
-              attrType =
-                   DirectoryServer.getAttributeType(OP_ATTR_USER_TIME_LIMIT,
-                                                    true);
-              attrList = saslAuthUserEntry.getAttribute(attrType);
-              if ((attrList != null) && (attrList.size() == 1))
-              {
-                Attribute a = attrList.get(0);
-                LinkedHashSet<AttributeValue>  values = a.getValues();
-                Iterator<AttributeValue> iterator = values.iterator();
-                if (iterator.hasNext())
-                {
-                  AttributeValue v = iterator.next();
-                  if (iterator.hasNext())
-                  {
-                    int msgID = MSGID_BIND_MULTIPLE_USER_TIME_LIMITS;
-                    String message = getMessage(msgID, userDNString);
-                    logError(ErrorLogCategory.CORE_SERVER,
-                             ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-                  }
-                  else
-                  {
-                    try
-                    {
-                      timeLimit = Integer.parseInt(v.getStringValue());
-                    }
-                    catch (Exception e)
-                    {
-                      if (debugEnabled())
-                      {
-                        TRACER.debugCaught(DebugLogLevel.ERROR, e);
-                      }
-
-                      int msgID = MSGID_BIND_CANNOT_PROCESS_USER_TIME_LIMIT;
-                      String message =
-                           getMessage(msgID, v.getStringValue(), userDNString);
-                      logError(ErrorLogCategory.CORE_SERVER,
-                               ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-                    }
-                  }
-                }
-              }
-
-
-              // See if the user's entry contains a custom lookthrough limit.
-              attrType =
-                   DirectoryServer.getAttributeType(
-                       OP_ATTR_USER_LOOKTHROUGH_LIMIT, true);
-              attrList = saslAuthUserEntry.getAttribute(attrType);
-              if ((attrList != null) && (attrList.size() == 1))
-              {
-                Attribute a = attrList.get(0);
-                LinkedHashSet<AttributeValue>  values = a.getValues();
-                Iterator<AttributeValue> iterator = values.iterator();
-                if (iterator.hasNext())
-                {
-                  AttributeValue v = iterator.next();
-                  if (iterator.hasNext())
-                  {
-                    int msgID = MSGID_BIND_MULTIPLE_USER_LOOKTHROUGH_LIMITS;
-                    String message = getMessage(msgID, userDNString);
-                    logError(ErrorLogCategory.CORE_SERVER,
-                             ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-                  }
-                  else
-                  {
-                    try
-                    {
-                      lookthroughLimit = Integer.parseInt(v.getStringValue());
-                    }
-                    catch (Exception e)
-                    {
-                      if (debugEnabled())
-                      {
-                        TRACER.debugCaught(DebugLogLevel.ERROR, e);
-                      }
-
-                      int msgID =
-                          MSGID_BIND_CANNOT_PROCESS_USER_LOOKTHROUGH_LIMIT;
-                      String message =
-                           getMessage(msgID, v.getStringValue(), userDNString);
-                      logError(ErrorLogCategory.CORE_SERVER,
-                               ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-                    }
-                  }
-                }
-              }
-            }
-          }
-          else if (resultCode == ResultCode.SASL_BIND_IN_PROGRESS)
-          {
-            // FIXME -- Is any special processing needed here?
-          }
-          else
-          {
-            if (pwPolicyState != null)
-            {
-              if (saslHandler.isPasswordBased(saslMechanism))
-              {
-
-                if (pwPolicyState.getPolicy().getLockoutFailureCount() > 0)
-                {
-                  pwPolicyState.updateAuthFailureTimes();
-                  if (pwPolicyState.lockedDueToFailures())
-                  {
-                    AccountStatusNotificationType notificationType;
-                    int msgID;
-                    String message;
-
-                    int lockoutDuration = pwPolicyState.getSecondsUntilUnlock();
-                    if (lockoutDuration > -1)
-                    {
-                      notificationType = AccountStatusNotificationType.
-                                              ACCOUNT_TEMPORARILY_LOCKED;
-                      msgID   = MSGID_BIND_ACCOUNT_TEMPORARILY_LOCKED;
-                      message = getMessage(msgID,
-                                     secondsToTimeString(lockoutDuration));
-                    }
-                    else
-                    {
-                      notificationType = AccountStatusNotificationType.
-                                              ACCOUNT_PERMANENTLY_LOCKED;
-                      msgID   = MSGID_BIND_ACCOUNT_PERMANENTLY_LOCKED;
-                      message = getMessage(msgID);
-                    }
-
-                    pwPolicyState.generateAccountStatusNotification(
-                         notificationType, userEntryDN, msgID, message);
-                  }
-                }
-              }
-            }
-          }
-
-          break;
-
-
-        default:
-          // Send a protocol error response to the client and disconnect.
-          // NYI
-          return;
-      }
-    }
-
-
-    // Update the user's account with any password policy changes that may be
-    // required.
-    try
-    {
-      if (pwPolicyState != null)
-      {
-        pwPolicyState.updateUserEntry();
-      }
-    }
-    catch (DirectoryException de)
-    {
-      if (debugEnabled())
-      {
-        TRACER.debugCaught(DebugLogLevel.ERROR, de);
-      }
-
-      setResponseData(de);
-    }
-
-
-    // Invoke the post-operation bind plugins.
-    if (! skipPostOperation)
-    {
-      PostOperationPluginResult postOpResult =
-           pluginConfigManager.invokePostOperationBindPlugins(this);
-      if (postOpResult.connectionTerminated())
-      {
-        // There's no point in continuing with anything.  Log the result
-        // and return.
-        setResultCode(ResultCode.CANCELED);
-
-        int msgID = MSGID_CANCELED_BY_PREOP_DISCONNECT;
-        appendErrorMessage(getMessage(msgID));
-
-        processingStopTime = System.currentTimeMillis();
-
-        logBindResponse(this);
-        pluginConfigManager.invokePostResponseBindPlugins(this);
-        return;
-      }
-    }
-
-
-    // Update the authentication information for the user.
-    if ((getResultCode() == ResultCode.SUCCESS) && (authInfo != null))
-    {
-      authenticatedUserEntry = authInfo.getAuthenticationEntry();
-      clientConnection.setAuthenticationInfo(authInfo);
-      clientConnection.setSizeLimit(sizeLimit);
-      clientConnection.setTimeLimit(timeLimit);
-      clientConnection.setLookthroughLimit(lookthroughLimit);
-      clientConnection.setMustChangePassword(mustChangePassword);
-
-      if (returnAuthzID)
-      {
-        responseControls.add(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);
-        responseControls.add(pwpControl);
-      }
-      else
-      {
-        if (pwPolicyErrorType == PasswordPolicyErrorType.PASSWORD_EXPIRED)
-        {
-          responseControls.add(new PasswordExpiredControl());
-        }
-        else if (pwPolicyWarningType ==
-                 PasswordPolicyWarningType.TIME_BEFORE_EXPIRATION)
-        {
-          responseControls.add(new PasswordExpiringControl(
-                                        pwPolicyWarningValue));
-        }
-      }
-    }
-    else
-    {
-      if (pwPolicyControlRequested)
-      {
-        PasswordPolicyResponseControl pwpControl =
-             new PasswordPolicyResponseControl(pwPolicyWarningType,
-                                               pwPolicyWarningValue,
-                                               pwPolicyErrorType);
-        responseControls.add(pwpControl);
-      }
-      else
-      {
-        if (pwPolicyErrorType == PasswordPolicyErrorType.PASSWORD_EXPIRED)
-        {
-          responseControls.add(new PasswordExpiredControl());
-        }
-      }
-    }
-
-
-    // Unset the "bind in progress" flag to allow other operations to be
-    // processed.
-    // FIXME -- Make sure this also gets unset at every possible point at which
-    // the bind could fail and this method could return early.
-    clientConnection.setBindInProgress(false);
-
-
-    // Stop the processing timer.
-    processingStopTime = System.currentTimeMillis();
-
-
-    // Send the bind response to the client.
-    clientConnection.sendResponse(this);
-
-
-    // Log the bind response.
-    logBindResponse(this);
-
-
-    // Invoke the post-response bind plugins.
-    pluginConfigManager.invokePostResponseBindPlugins(this);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final CancelResult cancel(CancelRequest cancelRequest)
-  {
-    cancelRequest.addResponseMessage(getMessage(MSGID_CANNOT_CANCEL_BIND));
-    return CancelResult.CANNOT_CANCEL;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final CancelRequest getCancelRequest()
-  {
-    return null;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  protected boolean setCancelRequest(CancelRequest cancelRequest)
-  {
-    // Bind operations cannot be canceled.
-    return false;
-  }
-
+  public abstract void setUserEntryDN(DN userEntryDN);
 
 
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final void toString(StringBuilder buffer)
-  {
-    buffer.append("BindOperation(connID=");
-    buffer.append(clientConnection.getConnectionID());
-    buffer.append(", opID=");
-    buffer.append(operationID);
-    buffer.append(", protocol=\"");
-    buffer.append(clientConnection.getProtocol());
-    buffer.append(" ");
-    buffer.append(protocolVersion);
-    buffer.append("\", dn=");
-    buffer.append(rawBindDN);
-    buffer.append(", authType=");
-    buffer.append(authType);
-    buffer.append(")");
-  }
 }
-

--
Gitblit v1.10.0