'A customized control flow graph BFS implementation with the following rules:
- Call edges are not followed.
- Syscall edges are not followed.
:param networkx.DiGraph g: The graph.
:param list starts: A collection of beginning nodes to start graph traversal.
:param func callback: Callback function for each edge and node.
:param dict blockaddr_to_function: A mapping between block addresses to Function instances.
:param angr.knowledge.FunctionManager known_functions: Already recovered functions.
:param set traversed_cfg_nodes: A set of CFGNodes that are traversed before.
:return: None'

def _graph_bfs_custom(self, g, starts, callback, blockaddr_to_function, known_functions, traversed_cfg_nodes=None):

    stack = OrderedSet(starts)
    traversed = (set() if (traversed_cfg_nodes is None) else traversed_cfg_nodes)
    while stack:
        n = stack.pop(last=False)
        if (n in traversed):
            continue
        traversed.add(n)
        if n.has_return:
            callback(n, None, {'jumpkind': 'Ijk_Ret'}, blockaddr_to_function, known_functions, None)
        elif (g.out_degree(n) == 0):
            callback(n, None, None, blockaddr_to_function, known_functions, None)
        else:
            all_out_edges = g.out_edges(n, data=True)
            for (src, dst, data) in all_out_edges:
                callback(src, dst, data, blockaddr_to_function, known_functions, all_out_edges)
                jumpkind = data.get('jumpkind', '')
                if (not ((jumpkind == 'Ijk_Call') or jumpkind.startswith('Ijk_Sys'))):
                    if ((dst not in stack) and (dst not in traversed)):
                        stack.add(dst)
