private AANode<T> remove(T element, AANode<T> node) {
    if (node == null) {
      return node;
    } else if (element.compareTo(node.getValue()) > 0) {
      node.setRight(remove(element, node.getRight()));
    } else if (element.compareTo(node.getValue()) < 0) {
      node.setLeft(remove(element, node.getLeft()));
    } else {
      if (node.getLevel() == 1) {
        return null;
      } else if (node.getLeft() == null) {
        AANode<T> left = getSuccessor(node);
        node.setRight(remove(left.getValue(), node.getRight()));
        node.setValue(left.getValue());
      } else {
        AANode<T> left = getPredecessor(node);
        node.setLeft(remove(left.getValue(), node.getLeft()));
        node.setValue(left.getValue());
      }
    }

    node = decreaseLevel(node);
    node = skew(node);
    node.setRight(skew(node.getRight()));
    if (node.getRight() != null) {
      node.getRight().setRight(skew(node.getRight().getRight()));
    }

    node = split(node);
    node.setRight(split(node).getRight());

    return node;
  }
 private AANode<T> split(AANode<T> node) {
   if (node == null) {
     return null;
   } else if (node.getLeft() == null) {
     return node;
   } else if (node.getLeft().getLevel() == node.getLevel()) {
     AANode<T> left = node.getLeft();
     node.setLeft(left.getRight());
     left.setRight(node);
     return left;
   } else {
     return node;
   }
 }
 private AANode<T> skew(AANode<T> node) {
   if (node == null) {
     return null;
   } else if (node.getRight() == null || node.getRight().getRight() == null) {
     return node;
   } else if (node.getLevel() == node.getRight().getRight().getLevel()) {
     AANode<T> right = node.getRight();
     node.setRight(right.getLeft());
     right.setLeft(node);
     right.setLevel(right.getLevel() + 1);
     return right;
   } else {
     return node;
   }
 }
  private AANode<T> insert(T element, AANode<T> node) {
    if (node == null) {
      node = new AANode<>(element);
    } else if (element.compareTo(node.getValue()) < 0) {
      node.setLeft(insert(element, node.getLeft()));
    } else if (element.compareTo(node.getValue()) > 0) {
      node.setRight(insert(element, node.getRight()));
    } else {
      return node;
    }

    node = skew(node);
    node = split(node);

    return node;
  }