isAncestor(targetId: string, ancestorId: string) {
  let curNode = this.nodes.get(targetId);
  while (curNode) {
    if (curNode.parentId === ancestorId) return true;
    curNode = this.nodes.get(curNode.parentId);
  }
  return false;
}
doOperation(tree: Tree<T>): OperationLog<T> {
  const node = tree.get(this.id);
  const oldParentId = node.parentId;

  if (tree.isAncestor(this.parentId, this.id)) {
    return { operation: this, oldParentId };
  }

  tree.removeNode(this.id);
  tree.attachNode(this.id, this.parentId);
  return { operation: this, oldParentId };
}