refactor mixins/tree::hasChild() to hasDescendant() and make it more backboney