docs: public Iterator<K> tailIterator(@NotNull final K key) {
          return new Iterator<K>() {
  
              private Stack<TreePos<K>> stack;
              private boolean hasNext;
              private boolean hasNextValid;
  
              @Override
              public boolean hasNext() {
                  if (hasNextValid) {
                      return hasNext;
                  }
                  hasNextValid = true;
                  if (stack == null) {
                      Node<K> root = getRoot();
                      if (root == null) {
                          hasNext = false;
                          return hasNext;
                      }
                      stack = new Stack<>();
                      if (!root.getLess(key, stack)) {
                          stack.push(new TreePos<>(root));
                      }
                  }
                  TreePos<K> treePos = stack.peek();
                  if (treePos.node.isLeaf()) {
                      while (treePos.pos >= (treePos.node.isTernary() ? 2 : 1)) {
                          stack.pop();
                          if (stack.isEmpty()) {
                              hasNext = false;
                              return hasNext;
                          }
                          treePos = stack.peek();
                      }
                  } else {
                      if (treePos.pos == 0) {
                          treePos = new TreePos<>(treePos.node.getFirstChild());
                      } else if (treePos.pos == 1) {
                          treePos = new TreePos<>(treePos.node.getSecondChild());
                      } else {
                          treePos = new TreePos<>(treePos.node.getThirdChild());
                      }
                      stack.push(treePos);
                      while (!treePos.node.isLeaf()) {
                          treePos = new TreePos<>(treePos.node.getFirstChild());
                          stack.push(treePos);
                      }
                  }
                  treePos.pos++;
                  hasNext = true;
                  return hasNext;
              }
  
              @Override
              public K next() {
                  if (!hasNext()) {
                      throw new NoSuchElementException();
                  }
                  hasNextValid = false;
                  TreePos<K> treePos = stack.peek();
                  // treePos.pos must be 1 or 2 here
                  return treePos.pos == 1 ? treePos.node.getFirstKey() : treePos.node.getSecondKey();
              }
  
              @Override
              public void remove() {
                  throw new UnsupportedOperationException();
              }
          };
      }