def _internal_get_biconnected_components_edge_lists(graph):
list_of_components = []<EOL>num_nodes = graph.num_nodes()<EOL>num_edges = graph.num_edges()<EOL>if num_nodes <= <NUM_LIT:2>:<EOL><INDENT>if num_edges == <NUM_LIT:1>:<EOL><INDENT>list_of_components.append(graph.get_all_edge_ids())<EOL><DEDENT>return list_of_components<EOL><DEDENT>dfs_count = <NUM_LIT:0><EOL>edge_stack = deque()<EOL>dfs_stack = deque()<EOL>visited = defaultdict(lambda: False)<EOL>parent = defaultdict(lambda: None)<EOL>depth = {}<EOL>low = {}<EOL>preorder_processed = defaultdict(lambda: False)<EOL>postorder_processed = defaultdict(lambda: False)<EOL>unvisited_nodes = set(graph.get_all_node_ids())<EOL>while len(unvisited_nodes) > <NUM_LIT:0>:<EOL><INDENT>u = unvisited_nodes.pop()<EOL>parent[u] = u<EOL>stack_frame = {<EOL>'<STR_LIT:u>': u,<EOL>'<STR_LIT:v>': None,<EOL>'<STR_LIT>': graph.neighbors(u)<EOL>}<EOL>dfs_stack.appendleft(stack_frame)<EOL>while len(dfs_stack) > <NUM_LIT:0>:<EOL><INDENT>frame = dfs_stack.popleft()<EOL>u = frame['<STR_LIT:u>']<EOL>v = frame['<STR_LIT:v>']<EOL>if not visited[u]:<EOL><INDENT>if u in unvisited_nodes:<EOL><INDENT>unvisited_nodes.remove(u)<EOL><DEDENT>visited[u] = True<EOL>dfs_count += <NUM_LIT:1><EOL>depth[u] = dfs_count<EOL>low[u] = depth[u]<EOL>if len(frame['<STR_LIT>']) > <NUM_LIT:0>:<EOL><INDENT>v = frame['<STR_LIT>'].pop()<EOL>frame['<STR_LIT:v>'] = v<EOL><DEDENT><DEDENT>if v is None:<EOL><INDENT>continue<EOL><DEDENT>if not preorder_processed[v]:<EOL><INDENT>node_v = graph.get_node(v)<EOL>for edge_id in node_v['<STR_LIT>']:<EOL><INDENT>edge = graph.get_edge(edge_id)<EOL>tpl_a = (u, v)<EOL>tpl_b = (v, u)<EOL>if tpl_a == edge['<STR_LIT>'] or tpl_b == edge['<STR_LIT>']:<EOL><INDENT>edge_stack.appendleft(edge_id)<EOL>break<EOL><DEDENT><DEDENT>parent[v] = u<EOL>preorder_processed[v] = True<EOL>dfs_stack.appendleft(frame)<EOL>new_frame = {<EOL>'<STR_LIT:u>': v,<EOL>'<STR_LIT:v>': None,<EOL>'<STR_LIT>': graph.neighbors(v)<EOL>}<EOL>dfs_stack.appendleft(new_frame)<EOL>continue<EOL><DEDENT>elif not postorder_processed[v] and u == parent[v]:<EOL><INDENT>if low[v] >= depth[u]:<EOL><INDENT>component = output_component(graph, edge_stack, u, v)<EOL>if len(component) > <NUM_LIT:2>:<EOL><INDENT>list_of_components.append(component)<EOL><DEDENT><DEDENT>low[u] = min(low[u], low[v])<EOL>postorder_processed[v] = True<EOL><DEDENT>elif visited[v] and (parent[u] != v) and (depth[v] < depth[u]):<EOL><INDENT>node_v = graph.get_node(v)<EOL>for edge_id in node_v['<STR_LIT>']:<EOL><INDENT>edge = graph.get_edge(edge_id)<EOL>tpl_a = (u, v)<EOL>tpl_b = (v, u)<EOL>if tpl_a == edge['<STR_LIT>'] or tpl_b == edge['<STR_LIT>']:<EOL><INDENT>edge_stack.appendleft(edge_id)<EOL>break<EOL><DEDENT><DEDENT>low[u] = min(low[u], depth[v])<EOL><DEDENT>if len(frame['<STR_LIT>']) > <NUM_LIT:0>:<EOL><INDENT>v = frame['<STR_LIT>'].pop()<EOL>frame['<STR_LIT:v>'] = v<EOL>dfs_stack.appendleft(frame)<EOL><DEDENT><DEDENT><DEDENT>return list_of_components<EOL>
Works on a single connected component to produce the edge lists of the biconnected components.
    Returns a list of lists, each containing the edges that combine to produce the connected component.
    Returns a single nested list with 1 edge if there is only 1 edge in the graph (a 2-node graph is a
    special case, generally considered to be a biconnected graph).
    Returns an empty list if there are no edges in the graph (i.e. if it's a single-node or empty graph).