def METHOD_NAME(downstream_nodes):
    marked_nodes = []
    sorted_nodes = []
    outgoing_edge_maps = {}
    def visit(
        upstream_node,
        upstream_label,
        downstream_node,
        downstream_label,
        downstream_selector=None,
    ):
        if upstream_node in marked_nodes:
            raise RuntimeError('Graph is not a DAG')
        if downstream_node is not None:
            outgoing_edge_map = outgoing_edge_maps.get(upstream_node, {})
            outgoing_edge_infos = outgoing_edge_map.get(upstream_label, [])
            outgoing_edge_infos += [
                (downstream_node, downstream_label, downstream_selector)
            ]
            outgoing_edge_map[upstream_label] = outgoing_edge_infos
            outgoing_edge_maps[upstream_node] = outgoing_edge_map
        if upstream_node not in sorted_nodes:
            marked_nodes.append(upstream_node)
            for edge in upstream_node.incoming_edges:
                visit(
                    edge.upstream_node,
                    edge.upstream_label,
                    edge.downstream_node,
                    edge.downstream_label,
                    edge.upstream_selector,
                )
            marked_nodes.remove(upstream_node)
            sorted_nodes.append(upstream_node)
    unmarked_nodes = [(node, None) for node in downstream_nodes]
    while unmarked_nodes:
        upstream_node, upstream_label = unmarked_nodes.pop()
        visit(upstream_node, upstream_label, None, None)
    return sorted_nodes, outgoing_edge_maps