! @brief Recursively search for children that match a given predicate.
        @param self
        @param predicate A callable accepting a single argument for the node to examine. If the
            predicate returns True, then that node is added to the result list and no further
            searches on that node's children are performed. A False predicate result causes the
            node's children to be searched.
        @param breadth_first Whether to search breadth first. Pass False to search depth first.
        @returns List of matching child nodes, or an empty list if no matches were found.

def find_children(self, predicate, breadth_first=True):
        """! @brief Recursively search for children that match a given predicate.
        @param self
        @param predicate A callable accepting a single argument for the node to examine. If the
            predicate returns True, then that node is added to the result list and no further
            searches on that node's children are performed. A False predicate result causes the
            node's children to be searched.
        @param breadth_first Whether to search breadth first. Pass False to search depth first.
        @returns List of matching child nodes, or an empty list if no matches were found.
        """
        def _search(node, klass):
            results = []
            childrenToExamine = []
            for child in node.children:
                if predicate(child):
                    results.append(child)
                elif not breadth_first:
                    results.extend(_search(child, klass))
                elif breadth_first:
                    childrenToExamine.append(child)
                
            if breadth_first:
                for child in childrenToExamine:
                    results.extend(_search(child, klass))
            return results
        
        return _search(self, predicate)