public static function applyCallback(callable $callback, NodeInterface $root, $targetClass = ChildNodeInterface::class)
    {
        $processed = [];
        $f = function (ChildNodeInterface $targetNode) use ($callback, $targetClass, &$f, &$processed) {
            if (in_array($targetNode, $processed, true)) {
                return;
            }
            $nodes = $targetNode instanceof ParentNodeInterface
                ? $targetNode->getChildrenRecursive()->toArray()
                : [];
            $nodes[] = $targetNode;

            /** @var NodeInterface $node */
            foreach ($nodes as $node) {
                $node instanceof $targetClass && call_user_func($callback, $node);
                $node instanceof ParentNodeInterface && $node->children()->onItemAdd($f);
                $processed[] = $node;
            }
        };
        $f($root);
    }