/** ************************ TEST MUTATION ******************************************* */
 @Test
 public void testOversizedMiddleInsert() {
   TreeSet<Integer> canon = new TreeSet<>();
   for (int i = 0; i < 10000000; i++) canon.add(i);
   Object[] btree =
       BTree.build(Arrays.asList(Integer.MIN_VALUE, Integer.MAX_VALUE), UpdateFunction.noOp());
   btree = BTree.update(btree, naturalOrder(), canon, UpdateFunction.<Integer>noOp());
   canon.add(Integer.MIN_VALUE);
   canon.add(Integer.MAX_VALUE);
   assertTrue(BTree.isWellFormed(btree, naturalOrder()));
   testEqual("Oversize", BTree.iterator(btree), canon.iterator());
 }
  private static RandomTree randomTreeByUpdate(int minSize, int maxSize) {
    assert minSize > 3;
    TreeSet<Integer> canonical = new TreeSet<>();

    ThreadLocalRandom random = ThreadLocalRandom.current();
    int targetSize = random.nextInt(minSize, maxSize);
    int maxModificationSize = random.nextInt(2, targetSize);
    Object[] accmumulate = BTree.empty();
    int curSize = 0;
    while (curSize < targetSize) {
      int nextSize = maxModificationSize == 1 ? 1 : random.nextInt(1, maxModificationSize);
      TreeSet<Integer> build = new TreeSet<>();
      for (int i = 0; i < nextSize; i++) {
        Integer next = random.nextInt();
        build.add(next);
        canonical.add(next);
      }
      accmumulate =
          BTree.update(accmumulate, naturalOrder(), build, UpdateFunction.<Integer>noOp());
      curSize += nextSize;
      maxModificationSize = Math.min(maxModificationSize, targetSize - curSize);
    }
    return new RandomTree(canonical, BTreeSet.<Integer>wrap(accmumulate, naturalOrder()));
  }