/** Test If we have only the required values. */
  @Test(dataProvider = "persistentSearchChangeTypeData")
  public void checkRequiredValuesTest(Map<Integer, String> exceptedValues) throws Exception {
    // Retrieve the values
    PersistentSearchChangeType[] vals = PersistentSearchChangeType.values();

    // Check if we have the correct number
    assertEquals(vals.length, exceptedValues.size());

    // Check if we have the correct int value
    for (PersistentSearchChangeType val : vals) {
      assertTrue(exceptedValues.containsKey(val.intValue()));
    }
  }
  /** Test EntryChangeNotificationControl. */
  @Test(dataProvider = "entryChangeNotificationControl")
  public void checkEntryChangeNotificationControlTest(
      boolean isCritical, long changeNumber, String dnString) throws Exception {
    // Test constructor EntryChangeNotificationControl
    // (PersistentSearchChangeType changeType,long changeNumber)
    PersistentSearchChangeType[] types = PersistentSearchChangeType.values();
    EntryChangeNotificationControl ecnc = null;
    EntryChangeNotificationControl newEcnc;
    ByteStringBuilder bsb = new ByteStringBuilder();
    ASN1Writer writer = ASN1.getWriter(bsb);
    for (PersistentSearchChangeType type : types) {
      ecnc = new EntryChangeNotificationControl(type, changeNumber);
      assertNotNull(ecnc);
      assertEquals(OID_ENTRY_CHANGE_NOTIFICATION, ecnc.getOID());
      assertEquals(changeNumber, ecnc.getChangeNumber());
      assertEquals(type, ecnc.getChangeType());
      assertNull(ecnc.getPreviousDN());
      assertEquals(false, ecnc.isCritical());
      checkEntryChangeNotificationControlToString(ecnc);

      // also check encode/decode
      try {
        bsb.clear();
        ecnc.write(writer);
        LDAPControl control = LDAPReader.readControl(ASN1.getReader(bsb));
        newEcnc =
            EntryChangeNotificationControl.DECODER.decode(control.isCritical(), control.getValue());
        assertNotNull(newEcnc);
        assertEquals(ecnc.getOID(), newEcnc.getOID());
        assertEquals(ecnc.getChangeNumber(), newEcnc.getChangeNumber());
        assertEquals(ecnc.getChangeType(), newEcnc.getChangeType());
        assertNull(newEcnc.getPreviousDN());
        assertEquals(ecnc.isCritical(), newEcnc.isCritical());
      } catch (DirectoryException e) {
        fail();
      }
    }

    // Test constructor EntryChangeNotificationControl
    // (PersistentSearchChangeType changeType, DN previousDN, long
    // changeNumber)
    DN dn = DN.valueOf(dnString);
    for (PersistentSearchChangeType type : types) {
      ecnc = new EntryChangeNotificationControl(type, dn, changeNumber);
      assertNotNull(ecnc);
      assertEquals(OID_ENTRY_CHANGE_NOTIFICATION, ecnc.getOID());
      assertEquals(changeNumber, ecnc.getChangeNumber());
      assertEquals(type, ecnc.getChangeType());
      assertEquals(dn, ecnc.getPreviousDN());
      assertEquals(false, ecnc.isCritical());
      checkEntryChangeNotificationControlToString(ecnc);

      // also check encode/decode
      try {
        bsb.clear();
        ecnc.write(writer);
        LDAPControl control = LDAPReader.readControl(ASN1.getReader(bsb));
        newEcnc =
            EntryChangeNotificationControl.DECODER.decode(control.isCritical(), control.getValue());
        assertNotNull(newEcnc);
        assertEquals(ecnc.getOID(), newEcnc.getOID());
        assertEquals(ecnc.getChangeNumber(), newEcnc.getChangeNumber());
        assertEquals(ecnc.getChangeType(), newEcnc.getChangeType());
        assertEquals(ecnc.getPreviousDN(), newEcnc.getPreviousDN());
        assertEquals(ecnc.isCritical(), newEcnc.isCritical());
      } catch (DirectoryException e) {
        assertNotEquals(
            type.compareTo(MODIFY_DN),
            0,
            "couldn't decode a control with previousDN not null and type=modDN");
      }
    }

    // Test constructor EntryChangeNotificationControl(boolean
    // isCritical, PersistentSearchChangeType changeType,
    // DN previousDN, long changeNumber)
    for (PersistentSearchChangeType type : types) {
      ecnc = new EntryChangeNotificationControl(isCritical, type, dn, changeNumber);
      assertNotNull(ecnc);
      assertEquals(OID_ENTRY_CHANGE_NOTIFICATION, ecnc.getOID());
      assertEquals(changeNumber, ecnc.getChangeNumber());
      assertEquals(type, ecnc.getChangeType());
      assertEquals(dn, ecnc.getPreviousDN());
      assertEquals(isCritical, ecnc.isCritical());
      checkEntryChangeNotificationControlToString(ecnc);

      // also check encode/decode
      try {
        bsb.clear();
        ecnc.write(writer);
        LDAPControl control = LDAPReader.readControl(ASN1.getReader(bsb));
        newEcnc =
            EntryChangeNotificationControl.DECODER.decode(control.isCritical(), control.getValue());
        assertNotNull(newEcnc);
        assertEquals(ecnc.getOID(), newEcnc.getOID());
        assertEquals(ecnc.getChangeNumber(), newEcnc.getChangeNumber());
        assertEquals(ecnc.getChangeType(), newEcnc.getChangeType());
        assertEquals(ecnc.getPreviousDN(), newEcnc.getPreviousDN());
        assertEquals(ecnc.isCritical(), newEcnc.isCritical());
      } catch (DirectoryException e) {
        assertNotEquals(
            type.compareTo(PersistentSearchChangeType.MODIFY_DN),
            0,
            "couldn't decode a control with previousDN not null and type=modDN");
      }
    }

    // Check error on decode
    try {
      LDAPControl control = new LDAPControl(OID_ENTRY_CHANGE_NOTIFICATION, isCritical);
      newEcnc =
          EntryChangeNotificationControl.DECODER.decode(control.isCritical(), control.getValue());
      fail();
    } catch (DirectoryException expected) {
      assertEquals(expected.getMessage(), CANNOT_DECODE_CHANGE_NOTIF_CONTROL_NO_VALUE);
    }
  }