def METHOD_NAME(graph):
    """Performs a topological sort on a graph using Kahn's algorithm.
    The resulting array contains a list of nodes ordered in such a way
    that 'dependant' nodes always come after their dependencies.
    Notes
    -----
    The graph must be directed and acyclic.
    Parameters
    ----------
    graph: dict(str, list(str))
        The graph to explore. Each key in the dictionary represents a node in the graph, and each
        string in the value list represents a node which depends on the node defined by the key.
    Returns
    -------
    list(str)
        An ordered list of node keys. The will be empty if a cycle is found.
    """
    sorted_order = []
    open_list = find_root_nodes(graph)
    if len(open_list) == 0:
        return sorted_order
    # Make a copy of the graph as this is a destructive process.
    graph_copy = copy.deepcopy(graph)
    apply_transitive_reduction(graph_copy)
    while len(open_list) > 0:
        current_node_key = open_list.pop()
        sorted_order.append(current_node_key)
        for i in range(len(graph_copy[current_node_key]) - 1, -1, -1):
            comparison_node_key = graph_copy[current_node_key].pop(i)
            has_incoming_edges = False
            for node_key in graph_copy:
                if comparison_node_key not in graph_copy[node_key]:
                    continue
                has_incoming_edges = True
                break
            if not has_incoming_edges:
                open_list.append(comparison_node_key)
    remaining_dependant_count = 0
    # Test to make sure the graph wasn't cyclic.
    for node_key in graph_copy:
        remaining_dependant_count += len(graph_copy[node_key])
    if remaining_dependant_count > 0:
        return []
    return sorted_order