/** {@inheritDoc} */
 @Override
 public Response<Void> bind(final BindRequest request) throws LdapException {
   Response<Void> response;
   if (request.getSaslConfig() != null) {
     response = saslBind(request);
   } else if (request.getDn() == null && request.getCredential() == null) {
     response = anonymousBind(request);
   } else {
     response = simpleBind(request);
   }
   return response;
 }
 /**
  * Performs a simple bind.
  *
  * @param request to bind with
  * @return bind response
  * @throws LdapException if an error occurs
  */
 protected Response<Void> simpleBind(final BindRequest request) throws LdapException {
   Response<Void> response = null;
   try {
     final LDAPResponseQueue queue =
         connection.bind(
             LDAPConnection.LDAP_V3,
             request.getDn(),
             request.getCredential().getBytes(),
             (LDAPResponseQueue) null,
             getLDAPConstraints(request));
     final LDAPResponse lr = (LDAPResponse) queue.getResponse();
     response = createResponse(request, null, lr);
   } catch (LDAPException e) {
     processLDAPException(e);
   }
   return response;
 }
  /**
   * Performs a sasl bind.
   *
   * @param request to bind with
   * @return bind response
   * @throws LdapException if an error occurs
   */
  protected Response<Void> saslBind(final BindRequest request) throws LdapException {
    try {
      final SaslConfig sc = request.getSaslConfig();
      switch (sc.getMechanism()) {
        case EXTERNAL:
          throw new UnsupportedOperationException("SASL External not supported");
          /* current implementation appears to be broken
           * see http://tinyurl.com/7ojdzlz
           * connection.bind(
           * (String) null,
           * sc.getAuthorizationId(),
           * new String[] {"EXTERNAL"},
           * null,
           * (Object) null);
           * break;
           */

        case DIGEST_MD5:
          connection.bind(
              (String) null,
              request.getDn(),
              new String[] {"DIGEST-MD5"},
              null,
              new SaslCallbackHandler(
                  null,
                  request.getCredential() != null ? request.getCredential().getString() : null));
          break;

        case CRAM_MD5:
          throw new UnsupportedOperationException("CRAM-MD5 not supported");

        case GSSAPI:
          throw new UnsupportedOperationException("GSSAPI not supported");

        default:
          throw new IllegalArgumentException(
              "Unknown SASL authentication mechanism: " + sc.getMechanism());
      }
    } catch (LDAPException e) {
      processLDAPException(e);
    }
    return new Response<Void>(null, ResultCode.SUCCESS);
  }