def _worklist_append(self, node_wrapper, worklist, worklist_set):
        """
        Append a CFGNode and its successors into the work-list, and respect the call-depth limit

        :param node_wrapper:    The NodeWrapper instance to insert.
        :param worklist:        The work-list, which is a list.
        :param worklist_set:    A set of all CFGNodes that are inside the work-list, just for the sake of fast look-up.
                                It will be updated as well.
        :returns:               A set of newly-inserted CFGNodes (not NodeWrapper instances).
        """

        if node_wrapper.cfg_node in worklist_set:
            # It's already in the work-list
            return

        worklist.append(node_wrapper)
        worklist_set.add(node_wrapper.cfg_node)

        stack = [ node_wrapper ]
        traversed_nodes = { node_wrapper.cfg_node }
        inserted = { node_wrapper.cfg_node }

        while stack:
            nw = stack.pop()
            n, call_depth = nw.cfg_node, nw.call_depth

            # Get successors
            edges = self._cfg.graph.out_edges(n, data=True)

            for _, dst, data in edges:
                if (dst not in traversed_nodes # which means we haven't touch this node in this appending procedure
                        and dst not in worklist_set): # which means this node is not in the work-list
                    # We see a new node!
                    traversed_nodes.add(dst)

                    if data['jumpkind'] == 'Ijk_Call':
                        if self._call_depth is None or call_depth < self._call_depth:
                            inserted.add(dst)
                            new_nw = DDGJob(dst, call_depth + 1)
                            worklist.append(new_nw)
                            worklist_set.add(dst)
                            stack.append(new_nw)
                    elif data['jumpkind'] == 'Ijk_Ret':
                        if call_depth > 0:
                            inserted.add(dst)
                            new_nw = DDGJob(dst, call_depth - 1)
                            worklist.append(new_nw)
                            worklist_set.add(dst)
                            stack.append(new_nw)
                    else:
                        new_nw = DDGJob(dst, call_depth)
                        inserted.add(dst)
                        worklist_set.add(dst)
                        worklist.append(new_nw)
                        stack.append(new_nw)

        return inserted
Append a CFGNode and its successors into the work-list, and respect the call-depth limit

        :param node_wrapper:    The NodeWrapper instance to insert.
        :param worklist:        The work-list, which is a list.
        :param worklist_set:    A set of all CFGNodes that are inside the work-list, just for the sake of fast look-up.
                                It will be updated as well.
        :returns:               A set of newly-inserted CFGNodes (not NodeWrapper instances).