'Update transition graphs of functions in function manager based on information passed in.
:param str jumpkind: Jumpkind.
:param CFGNode src_node: Source CFGNode
:param CFGNode dst_node: Destionation CFGNode
:param int ret_addr: The theoretical return address for calls
:return: None'

def _update_function_transition_graph(self, src_node_key, dst_node_key, jumpkind='Ijk_Boring', ins_addr=None, stmt_idx=None, confirmed=None):

    dst_node = self._graph_get_node(dst_node_key, terminator_for_nonexistent_node=True)
    if (src_node_key is None):
        self.kb.functions.function(dst_node.function_address, create=True)._register_nodes(True, dst_node.to_codenode())
        return
    src_node = self._graph_get_node(src_node_key, terminator_for_nonexistent_node=True)
    if (jumpkind == 'Ijk_Call'):
        ret_addr = src_node.return_target
        ret_node = (self.kb.functions.function(src_node.function_address, create=True)._get_block(ret_addr).codenode if ret_addr else None)
        self.kb.functions._add_call_to(function_addr=src_node.function_address, from_node=src_node.to_codenode(), to_addr=dst_node.addr, retn_node=ret_node, syscall=False, ins_addr=ins_addr, stmt_idx=stmt_idx)
    if jumpkind.startswith('Ijk_Sys'):
        self.kb.functions._add_call_to(function_addr=src_node.function_address, from_node=src_node.to_codenode(), to_addr=dst_node.addr, retn_node=src_node.to_codenode(), syscall=True, ins_addr=ins_addr, stmt_idx=stmt_idx)
    elif (jumpkind == 'Ijk_Ret'):
        self.kb.functions._add_return_from(function_addr=src_node.function_address, from_node=src_node.to_codenode(), to_node=dst_node.to_codenode())
        self.kb.functions._add_return_from_call(function_addr=dst_node.function_address, src_function_addr=src_node.function_address, to_node=dst_node.to_codenode())
    elif (jumpkind == 'Ijk_FakeRet'):
        self.kb.functions._add_fakeret_to(function_addr=src_node.function_address, from_node=src_node.to_codenode(), to_node=dst_node.to_codenode(), confirmed=confirmed)
    elif (jumpkind == 'Ijk_Boring'):
        src_obj = self.project.loader.find_object_containing(src_node.addr)
        dest_obj = self.project.loader.find_object_containing(dst_node.addr)
        if (src_obj is dest_obj):
            self.kb.functions._add_transition_to(function_addr=src_node.function_address, from_node=src_node.to_codenode(), to_node=dst_node.to_codenode(), ins_addr=ins_addr, stmt_idx=stmt_idx)
        else:
            self.kb.functions._add_outside_transition_to(function_addr=src_node.function_address, from_node=src_node.to_codenode(), to_node=dst_node.to_codenode(), to_function_addr=dst_node.function_address, ins_addr=ins_addr, stmt_idx=stmt_idx)
