/** Test int to type. */
  @Test(dataProvider = "persistentSearchChangeTypeData")
  public void checkIntToTypeTest(Map<Integer, String> exceptedValues) throws Exception {
    Set<Integer> keys = exceptedValues.keySet();

    Set<PersistentSearchChangeType> expectedTypes = new HashSet<>(4);

    for (int i = 1; i <= 15; i++) {
      expectedTypes.clear();
      for (int key : keys) {
        if ((i & key) != 0) {
          expectedTypes.add(PersistentSearchChangeType.valueOf(key));
        }
      }
      Set<PersistentSearchChangeType> returnTypes = PersistentSearchChangeType.intToTypes(i);
      assertEquals(expectedTypes.size(), returnTypes.size());
      for (PersistentSearchChangeType type : expectedTypes) {
        assertTrue(returnTypes.contains(type));
      }
    }

    // We should have an exception
    try {
      PersistentSearchChangeType.intToTypes(0);
      fail();
    } catch (LDAPException expected) {
      assertEquals(
          expected.getMessage(),
          "The provided integer value indicated that there were no persistent search change types, which is not allowed");
    }

    // We should have an exception
    int i = 16;
    try {
      PersistentSearchChangeType.intToTypes(i);
      fail();
    } catch (LDAPException expected) {
      assertEquals(
          expected.getMessage(),
          "The provided integer value "
              + i
              + " was outside the range of acceptable values for an encoded change type set");
    }
  }
  /** Test PersistentSearchControl. */
  @Test(dataProvider = "persistentSearchControl")
  public void checkPersistentSearchControlTest(
      boolean isCritical, boolean changesOnly, boolean returnECs) throws Exception {
    // Test constructor
    // CheclPersistentSearchControlTest(Set<PersistentSearchChangeType>
    // changeTypes, boolean changesOnly, boolean returnECs
    for (int i = 1; i <= 15; i++) {
      Set<PersistentSearchChangeType> returnTypes = PersistentSearchChangeType.intToTypes(i);
      PersistentSearchControl psc =
          new PersistentSearchControl(returnTypes, changesOnly, returnECs);
      assertNotNull(psc);
      assertEquals(changesOnly, psc.getChangesOnly());
      assertEquals(returnECs, psc.getReturnECs());
      assertEquals(returnTypes.size(), psc.getChangeTypes().size());
      assertEquals(OID_PERSISTENT_SEARCH, psc.getOID());
    }

    // Test constructor
    // CString oid, boolean isCritical,
    // Set<PersistentSearchChangeType> changeTypes,
    //    boolean changesOnly, boolean returnECs
    for (int i = 1; i <= 15; i++) {
      Set<PersistentSearchChangeType> returnTypes = PersistentSearchChangeType.intToTypes(i);
      PersistentSearchControl psc =
          new PersistentSearchControl(isCritical, returnTypes, changesOnly, returnECs);
      assertNotNull(psc);
      assertEquals(isCritical, psc.isCritical());
      assertEquals(OID_PERSISTENT_SEARCH, psc.getOID());
      assertEquals(changesOnly, psc.getChangesOnly());
      assertEquals(returnECs, psc.getReturnECs());
      assertEquals(returnTypes.size(), psc.getChangeTypes().size());
    }

    // Test encode/decode
    ByteStringBuilder bsb = new ByteStringBuilder();
    ASN1Writer writer = ASN1.getWriter(bsb);
    for (int i = 1; i <= 15; i++) {
      bsb.clear();
      Set<PersistentSearchChangeType> returnTypes = PersistentSearchChangeType.intToTypes(i);
      PersistentSearchControl psc =
          new PersistentSearchControl(isCritical, returnTypes, changesOnly, returnECs);
      psc.write(writer);
      LDAPControl control = LDAPReader.readControl(ASN1.getReader(bsb));
      psc = PersistentSearchControl.DECODER.decode(control.isCritical(), control.getValue());
      assertNotNull(psc);
      assertEquals(isCritical, psc.isCritical());
      assertEquals(OID_PERSISTENT_SEARCH, psc.getOID());
      assertEquals(changesOnly, psc.getChangesOnly());
      assertEquals(returnECs, psc.getReturnECs());
      assertEquals(returnTypes.size(), psc.getChangeTypes().size());

      // Check the toString
      String changeTypes = PersistentSearchChangeType.changeTypesToString(psc.getChangeTypes());
      String toString =
          "PersistentSearchControl(changeTypes=\""
              + changeTypes
              + "\",changesOnly="
              + psc.getChangesOnly()
              + ",returnECs="
              + psc.getReturnECs()
              + ")";
      assertEquals(psc.toString(), toString);

      // check null value for the control
      try {
        control = new LDAPControl(OID_PERSISTENT_SEARCH, isCritical);
        psc = PersistentSearchControl.DECODER.decode(control.isCritical(), control.getValue());
        fail();
      } catch (DirectoryException expected) {
        assertEquals(expected.getMessage(), CANNOT_DECODE_PERSISTENT_SEARCH_CONTROL_NO_VALUE);
      }

      // check invalid value for the control
      try {
        control =
            new LDAPControl(OID_PERSISTENT_SEARCH, isCritical, ByteString.valueOf("invalid value"));
        psc = PersistentSearchControl.DECODER.decode(control.isCritical(), control.getValue());
        fail();
      } catch (DirectoryException expected) {
        assertThat(expected.getMessage())
            .contains("Cannot decode the provided persistent search control");
      }
    }
  }