def _handle_successor(self, entry, successor, successors, _locals):
        """
        Returns a new PathWrapper instance for further analysis, or None if there is no immediate state to perform the
        analysis on.
        """

        state = successor
        all_successor_states = successors
        entry_wrapper = entry

        simrun = _locals['simrun']
        simrun_key = _locals['simrun_key']
        addr = _locals['addr']
        func_addr = _locals['func_addr']
        call_stack_suffix = _locals['call_stack_suffix']
        extra_info = _locals['extra_info']
        # retn_target_sources, extra_info
        successor_status = _locals['successor_status']

        # The PathWrapper instance to return
        pw = None

        successor_status[state] = ""

        new_state = state.copy()
        suc_jumpkind = state.scratch.jumpkind
        suc_exit_stmt_idx = state.scratch.exit_stmt_idx

        if suc_jumpkind in {'Ijk_EmWarn', 'Ijk_NoDecode', 'Ijk_MapFail', 'Ijk_InvalICache', 'Ijk_NoRedir',
                            'Ijk_SigTRAP', 'Ijk_SigSEGV', 'Ijk_ClientReq'}:
            # Ignore SimExits that are of these jumpkinds
            successor_status[state] = "Skipped"
            return

        if suc_jumpkind == "Ijk_FakeRet" and extra_info['call_target'] is not None:
            # if the call points to a SimProcedure that doesn't return, we don't follow the fakeret anymore
            if self.project.is_hooked(extra_info['call_target']):
                sim_proc = self.project._sim_procedures[extra_info['call_target']][0]
                if sim_proc.NO_RET:
                    return

        # Get target address
        try:
            target_addr = state.se.exactly_n_int(state.ip, 1)[0]
        except (simuvex.SimValueError, simuvex.SimSolverModeError):
            # It cannot be concretized currently. Maybe we can handle it later, maybe it just cannot be concretized
            target_addr = None
            if suc_jumpkind == "Ijk_Ret":
                target_addr = entry_wrapper.call_stack.current_return_target
                if target_addr is not None:
                    new_state.ip = new_state.se.BVV(target_addr, new_state.arch.bits)

        if target_addr is None:
            # Unlucky...
            return

        if state.thumb:
            # Make sure addresses are always odd. It is important to encode this information in the address for the
            # time being.
            target_addr |= 1

        self._pre_handle_successor_state(extra_info, suc_jumpkind, target_addr)

        # Remove pending targets - type 2
        tpl = self._generate_simrun_key(call_stack_suffix, target_addr, suc_jumpkind.startswith('Ijk_Sys'))
        cancelled_pending_entry = None
        if suc_jumpkind == 'Ijk_Ret' and tpl in self._pending_entries:

            # The fake ret is confirmed (since we are returning from the function it calls). Create an edge for it in
            # the graph
            cancelled_pending_entry = self._pending_entries[tpl]
            l.debug("Removing pending exits (type 2) to %s", hex(target_addr))
            del self._pending_entries[tpl]

        if suc_jumpkind == "Ijk_FakeRet":
            if target_addr == extra_info['last_call_exit_target']:
                l.debug("... skipping a fake return exit that has the same target with its call exit.")
                successor_status[state] = "Skipped"
                return

            if extra_info['skip_fakeret']:
                l.debug('... skipping a fake return exit since the function it\'s calling doesn\'t return')
                successor_status[state] = "Skipped - non-returning function 0x%x" % extra_info['call_target']
                return

        # TODO: Make it optional
        if (suc_jumpkind == 'Ijk_Ret' and
                    self._call_depth is not None and
                    len(entry_wrapper.call_stack) <= 1
            ):
            # We cannot continue anymore since this is the end of the function where we started tracing
            l.debug('... reaching the end of the starting function, skip.')
            successor_status[state] = "Skipped - reaching the end of the starting function"
            return

        # Create the new call stack of target block
        new_call_stack = self._create_new_call_stack(addr, all_successor_states, entry_wrapper, target_addr,
                                                     suc_jumpkind)
        # Create the callstack suffix
        new_call_stack_suffix = new_call_stack.stack_suffix(self._context_sensitivity_level)
        # Tuple that will be used to index this exit
        new_tpl = self._generate_simrun_key(new_call_stack_suffix, target_addr, suc_jumpkind.startswith('Ijk_Sys'))

        if isinstance(simrun, simuvex.SimIRSB):
            self._detect_loop(simrun,
                              new_tpl,
                              simrun_key,
                              new_call_stack_suffix,
                              target_addr,
                              suc_jumpkind,
                              entry_wrapper,
                              func_addr)

        # Generate the new BBL stack of target block
        if suc_jumpkind == "Ijk_Call" or suc_jumpkind.startswith('Ijk_Sys'):
            new_bbl_stack = entry_wrapper.bbl_stack_copy()
            new_bbl_stack.call(new_call_stack_suffix, target_addr)
            new_bbl_stack.push(new_call_stack_suffix, target_addr, target_addr)
        elif suc_jumpkind == "Ijk_Ret":
            new_bbl_stack = entry_wrapper.bbl_stack_copy()
            new_bbl_stack.ret(call_stack_suffix, func_addr)
        elif suc_jumpkind == "Ijk_FakeRet":
            new_bbl_stack = entry_wrapper.bbl_stack_copy()
        else:
            new_bbl_stack = entry_wrapper.bbl_stack_copy()
            new_bbl_stack.push(new_call_stack_suffix, func_addr, target_addr)

        new_path = self.project.factory.path(new_state)
        # We might have changed the mode for this basic block
        # before. Make sure it is still running in 'fastpath' mode
        # new_exit.state = self.project.simos.prepare_call_state(new_exit.state, initial_state=saved_state)
        new_path.state.set_mode('fastpath')
        pw = EntryWrapper(new_path,
                          self._context_sensitivity_level,
                          simrun_key,
                          suc_exit_stmt_idx,
                          call_stack=new_call_stack,
                          bbl_stack=new_bbl_stack,
                          cancelled_pending_entry=cancelled_pending_entry
                          )

        # Generate new exits
        if suc_jumpkind == "Ijk_Ret":
            # This is the real return exit
            # Check if this retn is inside our pending_exits set
            if new_tpl in self._pending_entries:

                # The fake ret is confirmed (since we are returning from the function it calls). Create an edge for it
                # in the graph. However, we don't want to create the edge here, since the destination node hasn't been
                # created yet at this moment. So we save the pending entry to the real entry, and create the FakeRet
                # edge when that entry is processed later.
                pending_entry = self._pending_entries[new_tpl]
                # TODO: is it possible that the cancelled_pending_entry has already been assigned before?
                pw.cancelled_pending_entry = pending_entry

                del self._pending_entries[new_tpl]

            successor_status[state] = "Appended"

        elif suc_jumpkind == "Ijk_FakeRet":
            # This is the default "fake" retn that generated at each
            # call. Save them first, but don't process them right
            # away
            # st = self.project.simos.prepare_call_state(new_state, initial_state=saved_state)
            st = new_state
            st.set_mode('fastpath')

            pw = None # clear the EntryWrapper
            pe = PendingExit(extra_info['call_target'], st, simrun_key, suc_exit_stmt_idx, new_bbl_stack,
                             new_call_stack
                             )
            self._pending_entries[new_tpl] = pe
            successor_status[state] = "Pended"

        elif 1 >= self._traced_addrs[new_call_stack_suffix][target_addr] and suc_jumpkind == "Ijk_Ret":
            # This is a corner case for the f****** ARM instruction
            # like
            # BLEQ <address>
            # If we have analyzed the boring exit before returning from that called address, we will lose the link
            # between the last block of the function being called and the basic block it returns to. We cannot
            # reanalyze the basic block as we are not flow-sensitive, but we can still record the connection and make
            # for it afterwards.
            pass

        else:
            successor_status[state] = "Appended"

        if extra_info['is_call_jump'] and extra_info['call_target'] in self._non_returning_functions:
            extra_info['skip_fakeret'] = True

        if pw:
            self._entries.append(pw)

    # SimAction handling
dataset/ETHPy150Open angr/angr/angr/analyses/cfg_accurate.py/CFGAccurate._handle_successor/swapped operands of `>=`