protected void deleteNode(@NotNull Node<K> n) {
    incModCount();

    Node<K> e = n;
    while (e.getParent() != null) e = e.getParent();
    assert e == root : e; // assert the node belongs to our tree

    if (n.getLeft() != null && n.getRight() != null) {
      // Copy key/value from predecessor and then delete it instead
      Node<K> pred = maximumNode(n.getLeft());

      //Color c = pred.color;
      //swap(n, pred);
      //assert pred.color == c;
      //pred.color = n.color;
      //n.color = c;

      n = swapWithMaxPred(n, pred);
    }

    assert n.getLeft() == null || n.getRight() == null;
    Node<K> child = n.getRight() == null ? n.getLeft() : n.getRight();
    if (isBlack(n)) {
      n.setColor(isBlack(child));
      deleteCase1(n);
    }
    replaceNode(n, child);

    if (!isBlack(root)) {
      root.setBlack();
    }

    assert nodeSize > 0 : nodeSize;
    nodeSize--;
    verifyProperties();
  }
protected void deleteNode(@NotNull Node<K> n)