def compare_graphs(before, after):
    """
    Compare two (sub)graphs.

    Note: a == b != b == a!

    :param before: A networkx (sub)graph.
    :param after: A networkx (sub)graph.
    :returns: A dict with changes.
    """
    res = {'added': [],
           'removed': [],
           'added_edge': [],
           'removed_edge': [],
           'chg_attr': []}

    for node in after.nodes():
        if node not in before.nodes():
            # add missing nodes
            if node not in res['added']:
                res['added'].append(node)
            for link in after.out_edges([node]):
                if link[1] not in before.nodes() \
                        and link[1] not in res['added']:
                    res['added'].append(link[1])
                res['added_edge'].append(link)
        else:
            # already there...
            if before.node[node]['attributes'] != \
                    after.node[node]['attributes']:
                res['chg_attr'].append((node,
                                        before.node[node]['attributes'],
                                        after.node[node]['attributes']))
    for node in before.nodes():
        if node not in after.nodes():
            res['removed'].append(node)
            for link in before.out_edges([node]):
                res['removed_edge'].append(link)
        else:
            # node exists lets check the edges.
            for link in after.out_edges([node]):
                if link not in before.out_edges([node]):
                    res['added_edge'].append(link)
            for link in before.out_edges([node]):
                if link not in after.out_edges([node]):
                    res['removed_edge'].append(link)
    return res