/**
   * Property test data.
   *
   * @return configuration properties
   */
  @DataProvider(name = "properties")
  public Object[][] createProperties() {
    final String p1 =
        "org.ldaptive.handler.RecursiveEntryHandler"
            + "{{searchAttribute=member}{mergeAttributes=mail,department}}";
    final RecursiveEntryHandler o1 = new RecursiveEntryHandler();
    o1.setSearchAttribute("member");
    o1.setMergeAttributes("mail", "department");

    final String p2 = "org.ldaptive.handler.MergeAttributeEntryHandler{ }";
    final MergeAttributeEntryHandler o2 = new MergeAttributeEntryHandler();

    final String p3 = "org.ldaptive.pool.IdlePruneStrategy{{prunePeriod=60}{idleTime=120}";
    final IdlePruneStrategy o3 = new IdlePruneStrategy();
    o3.setPrunePeriod(60);
    o3.setIdleTime(120);

    final String p4 =
        "org.ldaptive.sasl.CramMd5Config" + "{{securityStrength=LOW}{qualityOfProtection=AUTH}}";
    final CramMd5Config o4 = new CramMd5Config();
    o4.setSecurityStrength(SecurityStrength.LOW);
    o4.setQualityOfProtection(QualityOfProtection.AUTH);

    final String p5 = "{{mechanism=DIGEST_MD5}{authorizationId=test1}}";
    final SaslConfig o5 = new SaslConfig();
    o5.setMechanism(Mechanism.DIGEST_MD5);
    o5.setAuthorizationId("test1");

    final String p6 = "{mechanism=EXTERNAL}";
    final SaslConfig o6 = new SaslConfig();
    o6.setMechanism(Mechanism.EXTERNAL);

    return new Object[][] {
      new Object[] {
        p1, null, o1,
      },
      new Object[] {
        p2, null, o2,
      },
      new Object[] {
        p3, null, o3,
      },
      new Object[] {
        p4, null, o4,
      },
      new Object[] {
        p5, SaslConfig.class, o5,
      },
      new Object[] {
        p6, SaslConfig.class, o6,
      },
    };
  }
  /**
   * 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);
  }