@Test
  public void testTrim() throws Exception {
    ReplicationServer replicationServer = null;
    JEReplicaDB replicaDB = null;
    try {
      TestCaseUtils.startServer();
      replicationServer = configureReplicationServer(100, 5000);
      replicaDB = newReplicaDB(replicationServer);

      CSN[] csns = generateCSNs(1, 0, 5);

      replicaDB.add(new DeleteMsg(TEST_ROOT_DN, csns[0], "uid"));
      replicaDB.add(new DeleteMsg(TEST_ROOT_DN, csns[1], "uid"));
      replicaDB.add(new DeleteMsg(TEST_ROOT_DN, csns[2], "uid"));
      DeleteMsg update4 = new DeleteMsg(TEST_ROOT_DN, csns[3], "uid");

      // --
      // Iterator tests with changes persisted
      assertFoundInOrder(replicaDB, csns[0], csns[1], csns[2]);
      assertNotFound(replicaDB, csns[4], AFTER_MATCHING_KEY);

      assertEquals(replicaDB.getOldestCSN(), csns[0]);
      assertEquals(replicaDB.getNewestCSN(), csns[2]);

      // --
      // Cursor tests with changes persisted
      replicaDB.add(update4);

      assertFoundInOrder(replicaDB, csns[0], csns[1], csns[2], csns[3]);
      // Test cursor from existing CSN
      assertFoundInOrder(replicaDB, csns[2], csns[3]);
      assertFoundInOrder(replicaDB, csns[3]);
      assertNotFound(replicaDB, csns[4], AFTER_MATCHING_KEY);

      replicaDB.purgeUpTo(new CSN(Long.MAX_VALUE, 0, 0));

      int count = 0;
      boolean purgeSucceeded = false;
      final CSN expectedNewestCSN = csns[3];
      do {
        Thread.sleep(10);

        final CSN oldestCSN = replicaDB.getOldestCSN();
        final CSN newestCSN = replicaDB.getNewestCSN();
        purgeSucceeded = oldestCSN.equals(expectedNewestCSN) && newestCSN.equals(expectedNewestCSN);
        count++;
      } while (!purgeSucceeded && count < 100);
      assertTrue(purgeSucceeded);
    } finally {
      shutdown(replicaDB);
      remove(replicationServer);
    }
  }
  /** 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 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");
    }
  }