def METHOD_NAME(
    graph: GraphDefinition, selection_tree: OpSelectionNode, parent_handle: Optional[NodeHandle]
) -> SubselectedGraphDefinition:
    subgraph_deps: Dict[
        NodeInvocation,
        Dict[str, IDependencyDefinition],
    ] = {}
    subgraph_nodes: Dict[str, NodeDefinition] = {}
    for node in graph.nodes_in_topological_order:
        # skip if the node isn't selected
        if not selection_tree.has_child(node.name):
            continue
        node_handle = NodeHandle(node.name, parent=parent_handle)
        node_def: Union[SubselectedGraphDefinition, NodeDefinition] = node.definition
        node_selection_tree = selection_tree.get_child(node.name)
        # subselect graph if any nodes inside the graph are selected
        if isinstance(node, GraphNode) and not node_selection_tree.is_leaf:
            node_def = METHOD_NAME(
                node.definition,
                node_selection_tree,
                parent_handle=node_handle,
            )
        subgraph_nodes[node.name] = node_def
        # build dependencies for the node. we do it for both cases because nested graphs can have
        # inputs and outputs too
        node_deps: Dict[str, IDependencyDefinition] = {}
        for node_input in node.inputs():
            if graph.dependency_structure.has_direct_dep(node_input):
                node_output = graph.dependency_structure.get_direct_dep(node_input)
                if selection_tree.has_child(node_output.node_name):
                    node_deps[node_input.input_name] = DependencyDefinition(
                        node=node_output.node.name, output=node_output.output_name
                    )
            elif graph.dependency_structure.has_dynamic_fan_in_dep(node_input):
                node_output = graph.dependency_structure.get_dynamic_fan_in_dep(node_input)
                if selection_tree.has_child(node_output.node_name):
                    node_deps[node_input.input_name] = DynamicCollectDependencyDefinition(
                        node_name=node_output.node_name,
                        output_name=node_output.output_name,
                    )
            elif graph.dependency_structure.has_fan_in_deps(node_input):
                outputs = graph.dependency_structure.get_fan_in_deps(node_input)
                multi_dependencies = [
                    DependencyDefinition(
                        node=output_handle.node.name, output=output_handle.output_def.name
                    )
                    for output_handle in outputs
                    if (
                        isinstance(output_handle, NodeOutput)
                        and selection_tree.has_child(output_handle.node_name)
                    )
                ]
                node_deps[node_input.input_name] = MultiDependencyDefinition(
                    cast(
                        List[Union[DependencyDefinition, Type[MappedInputPlaceholder]]],
                        multi_dependencies,
                    )
                )
            # else input is unconnected
        dep_key = NodeInvocation(
            name=node.definition.name,
            alias=node.name,
            tags=node.tags,
            hook_defs=node.hook_defs,
            retry_policy=node.retry_policy,
        )
        subgraph_deps[dep_key] = node_deps
    # filter out unselected input/output mapping
    subgraph_input_mappings = [
        imap for imap in graph.input_mappings if imap.maps_to.node_name in subgraph_nodes.keys()
    ]
    subgraph_output_mappings = [
        omap for omap in graph.output_mappings if omap.maps_from.node_name in subgraph_nodes.keys()
    ]
    return SubselectedGraphDefinition(
        parent_graph_def=graph,
        dependencies=subgraph_deps,
        node_defs=list(subgraph_nodes.values()),
        input_mappings=subgraph_input_mappings,
        output_mappings=subgraph_output_mappings,
    )