'Create a Loop object for a strongly connected graph, and any strongly
connected subgraphs, if possible.
:param subg:    A strongly connected subgraph.
:param bigg:    The graph which subg is a subgraph of.
:return:        A list of Loop objects, some of which may be inside others,
but all need to be documented.'

def _parse_loop_graph(self, subg, bigg):

    loop_body_nodes = subg.nodes()[:]
    entry_edges = []
    break_edges = []
    continue_edges = []
    entry_node = None
    for node in loop_body_nodes:
        for pred_node in bigg.predecessors(node):
            if (pred_node not in loop_body_nodes):
                if ((entry_node is not None) and (entry_node != node)):
                    l.warning('Bad    loop:    more    than    one    entry    point    (%s,    %s)', entry_node, node)
                    return (None, [])
                entry_node = node
                entry_edges.append((pred_node, node))
                subg.add_edge(pred_node, node)
        for succ_node in bigg.successors(node):
            if (succ_node not in loop_body_nodes):
                break_edges.append((node, succ_node))
                subg.add_edge(node, succ_node)
    if (entry_node is None):
        entry_node = min(loop_body_nodes, key=(lambda n: n.addr))
        l.info("Couldn't    find    entry    point,    assuming    it's    the    first    by    address    (%s)", entry_node)
    acyclic_subg = subg.copy()
    for pred_node in subg.predecessors(entry_node):
        if (pred_node in loop_body_nodes):
            continue_edge = (pred_node, entry_node)
            acyclic_subg.remove_edge(*continue_edge)
            continue_edges.append(continue_edge)
    removed_exits = {}
    removed_entries = {}
    (tops, alls) = self._parse_loops_from_graph(acyclic_subg)
    for subloop in tops:
        if (subloop.entry in loop_body_nodes):
            for entry_edge in subloop.entry_edges:
                try:
                    subg.remove_edge(*entry_edge)
                except networkx.NetworkXError:
                    if (entry_edge in removed_entries):
                        subg.add_edge(removed_entries[entry_edge], subloop)
                        try:
                            subg.remove_edge(removed_entries[entry_edge], entry_edge[1])
                        except networkx.NetworkXError:
                            pass
                    else:
                        raise
                else:
                    subg.add_edge(entry_edge[0], subloop)
                    removed_entries[entry_edge] = subloop
            for exit_edge in subloop.break_edges:
                try:
                    subg.remove_edge(*exit_edge)
                except networkx.NetworkXError:
                    if (exit_edge in removed_entries):
                        subg.add_edge(subloop, removed_entries[exit_edge])
                        try:
                            subg.remove_edge(exit_edge[0], removed_entries[exit_edge])
                        except networkx.NetworkXError:
                            pass
                    else:
                        raise
                else:
                    subg.add_edge(subloop, exit_edge[1])
                    removed_exits[exit_edge] = subloop
            subg = filter((lambda g: (entry_node in g.nodes())), networkx.weakly_connected_component_subgraphs(subg))[0]
    me = Loop(entry_node, entry_edges, break_edges, continue_edges, loop_body_nodes, subg, tops[:])
    return (me, ([me] + alls))
