public TreeNode<N> deepCopy() {
    TreeNode<N> newNode = new TreeNode(this.value);

    for (TreeNode<N> child : this.children) newNode.addChildNode(child.deepCopy());

    return newNode;
  }
  public boolean addChildNode(TreeNode<N> child) {
    if (!children.contains(child)) {
      child.forgetParent();

      child.parent = this;
      return children.add(child);
    }

    return false;
  }
  public List<TreeNode<N>> getLeaves() {
    List<TreeNode<N>> leaves = new ArrayList<>();

    DepthFirstIterator it = this.new DepthFirstIterator();
    while (it.hasNext()) {
      TreeNode<N> node = it.next();
      if (node.isLeaf()) leaves.add(node);
    }

    return leaves;
  }
  public boolean removeChild(TreeNode<N> child) {
    if (this.children.contains(child)) {
      child.parent = null;
      return this.children.remove(child);
    }

    return false;
  }
  public void removeChildren() {
    for (TreeNode<N> child : this.children) child.parent = null;

    this.children.clear();
  }
 // <editor-fold defaultstate="collapsed" desc="Public methods">
 public boolean forgetParent() {
   if (this.parent != null) return parent.removeChild(this);
   return true;
 }