@Override
  @Nullable
  public BasePageMutable put(
      @NotNull ByteIterable key, @NotNull ByteIterable value, boolean overwrite, boolean[] result) {
    final SearchRes res = binarySearch(key);

    final BTreeMutable tree = (BTreeMutable) getTree();

    int pos = res.index;
    if (pos >= 0) {
      if (overwrite) {
        // key found
        final ILeafNode ln = res.key;
        if (ln == null) {
          throw new IllegalStateException("Leaf is expected to be found");
        }
        if (tree.allowsDuplicates) {
          // overwrite for tree with duplicates means add new value to existing key
          // manage sub-tree of duplicates
          // ln may be mutable or immutable, with dups or without
          LeafNodeDupMutable lnm = LeafNodeDupMutable.convert(ln, tree);
          if (lnm.put(value)) {
            tree.addExpiredLoggable(ln.getAddress());
            set(pos, lnm, null);
            result[0] = true;
          }
          // main tree size will be auto-incremented with some help from duplicates tree
        } else {
          if (!ln.isDupLeaf()) {
            // TODO: remove this forced update when we no longer need meta tree cloning
            tree.addExpiredLoggable(keysAddresses[pos]);
            set(pos, tree.createMutableLeaf(key, value), null);
            // this should be always true in order to keep up with keysAddresses[pos] expiration
            result[0] = true;
          }
        }
      }
      return null;
    }

    // if found - insert at this position, else insert after found
    if (pos < 0) pos = -pos - 1;
    else pos++;

    final BasePageMutable page = insertAt(pos, tree.createMutableLeaf(key, value), null);
    result[0] = true;
    tree.incrementSize();
    return page;
  }
 @Override
 @Nullable
 public BasePageMutable putRight(@NotNull ByteIterable key, @NotNull ByteIterable value) {
   final BTreeMutable tree = (BTreeMutable) getTree();
   if (size > 0) {
     final int pos = size - 1;
     final BaseLeafNode ln = getKey(pos);
     final int cmp = ln.compareKeyTo(key);
     if (cmp > 0) {
       throw new IllegalArgumentException("Key must be greater");
     } else if (cmp == 0) {
       if (tree.allowsDuplicates) {
         set(pos, LeafNodeDupMutable.convert(ln, tree).putRight(value), null);
         tree.addExpiredLoggable(ln.getAddress());
         return null;
       } else {
         throw new IllegalArgumentException("Key must not be equal");
       }
     }
   }
   final BasePageMutable page = insertAt(size, tree.createMutableLeaf(key, value), null);
   tree.incrementSize();
   return page;
 }