docs: private static <T extends Node> ImmutableList<T> getAllMatchingNodesOfType(
        Node rootSoyNode, final Class<T> classObject, final Predicate<T> filter) {
      final ImmutableList.Builder<T> matchedNodesBuilder = ImmutableList.builder();
      // optimization to avoid navigating into expr trees if we can't possibly match anything
      final boolean exploreExpressions = ExprNode.class.isAssignableFrom(classObject);
      visitAllNodes(
          rootSoyNode,
          new NodeVisitor<Node, VisitDirective>() {
            @Override
            public VisitDirective exec(Node node) {
              if (classObject.isInstance(node)) {
                T typedNode = classObject.cast(node);
                if (filter.test(typedNode)) {
                  matchedNodesBuilder.add(typedNode);
                }
              }
              if (!exploreExpressions && node instanceof ExprNode) {
                return VisitDirective.SKIP_CHILDREN;
              }
              return VisitDirective.CONTINUE;
            }
          });
      return matchedNodesBuilder.build();
    }