'Returns a new CFGJob instance for further analysis, or None if there is no immediate state to perform the
analysis on.
:param CFGJob job: The current job.'

def _handle_successor(self, job, successor, successors):

    state = successor
    all_successor_states = successors
    addr = job.addr
    pw = None
    job.successor_status[state] = ''
    new_state = state.copy()
    suc_jumpkind = state.history.jumpkind
    suc_exit_stmt_idx = state.scratch.exit_stmt_idx
    suc_exit_ins_addr = state.scratch.exit_ins_addr
    if (suc_jumpkind in {'Ijk_EmWarn', 'Ijk_NoDecode', 'Ijk_MapFail', 'Ijk_InvalICache', 'Ijk_NoRedir', 'Ijk_SigTRAP', 'Ijk_SigSEGV', 'Ijk_ClientReq'}):
        job.successor_status[state] = 'Skipped'
        return []
    call_target = job.extra_info['call_target']
    if ((suc_jumpkind == 'Ijk_FakeRet') and (call_target is not None)):
        if self.project.is_hooked(call_target):
            sim_proc = self.project._sim_procedures[call_target]
            if sim_proc.NO_RET:
                return []
    try:
        target_addr = state.se.exactly_n_int(state.ip, 1)[0]
    except (SimValueError, SimSolverModeError):
        target_addr = None
        if (suc_jumpkind == 'Ijk_Ret'):
            target_addr = job.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):
        return []
    if state.thumb:
        target_addr |= 1
    if (self._address_whitelist is not None):
        if (target_addr not in self._address_whitelist):
            l.debug('Successor    %#x    is    not    in    the    address    whitelist.    Skip.', target_addr)
            return []
    if (self._base_graph is not None):
        for (src_, dst_) in self._base_graph.edges_iter():
            if ((src_.addr == addr) and (dst_.addr == target_addr)):
                break
        else:
            l.debug('Edge    (%#x    ->    %#x)    is    not    found    in    the    base    graph.    Skip.', addr, target_addr)
            return []
    if suc_jumpkind.startswith('Ijk_Sys'):
        target_addr = self.project._simos.syscall(new_state).addr
    self._pre_handle_successor_state(job.extra_info, suc_jumpkind, target_addr)
    if (suc_jumpkind == 'Ijk_FakeRet'):
        if (target_addr == job.extra_info['last_call_exit_target']):
            l.debug('...    skipping    a    fake    return    exit    that    has    the    same    target    with    its    call    exit.')
            job.successor_status[state] = 'Skipped'
            return []
        if job.extra_info['skip_fakeret']:
            l.debug("...    skipping    a    fake    return    exit    since    the    function    it's    calling    doesn't    return")
            job.successor_status[state] = ('Skipped    -    non-returning    function    0x%x' % job.extra_info['call_target'])
            return []
    if ((suc_jumpkind == 'Ijk_Ret') and (self._call_depth is not None) and (len(job.call_stack) <= 1)):
        l.debug('...    reaching    the    end    of    the    starting    function,    skip.')
        job.successor_status[state] = 'Skipped    -    reaching    the    end    of    the    starting    function'
        return []
    new_call_stack = self._create_new_call_stack(addr, all_successor_states, job, target_addr, suc_jumpkind)
    new_call_stack_suffix = new_call_stack.stack_suffix(self._context_sensitivity_level)
    new_tpl = self._generate_block_id(new_call_stack_suffix, target_addr, suc_jumpkind.startswith('Ijk_Sys'))
    new_state.set_mode('fastpath')
    pw = CFGJob(target_addr, new_state, self._context_sensitivity_level, src_block_id=job.block_id, src_exit_stmt_idx=suc_exit_stmt_idx, src_ins_addr=suc_exit_ins_addr, call_stack=new_call_stack, jumpkind=suc_jumpkind)
    if (suc_jumpkind == 'Ijk_Ret'):
        job.successor_status[state] = 'Appended'
    elif (suc_jumpkind == 'Ijk_FakeRet'):
        st = new_state
        st.set_mode('fastpath')
        pw = None
        pe = PendingJob(job.func_addr, job.extra_info['call_target'], st, job.block_id, suc_exit_stmt_idx, suc_exit_ins_addr, new_call_stack)
        self._pending_jobs[new_tpl] = pe
        self._register_analysis_job(pe.caller_func_addr, pe)
        job.successor_status[state] = 'Pended'
    elif ((self._traced_addrs[new_call_stack_suffix][target_addr] >= 1) and (suc_jumpkind == 'Ijk_Ret')):
        pass
    else:
        job.successor_status[state] = 'Appended'
    if (job.extra_info['is_call_jump'] and (job.extra_info['call_target'] in self._non_returning_functions)):
        job.extra_info['skip_fakeret'] = True
    if (not pw):
        return []
    if (self._base_graph is not None):
        if next((en for en in self.jobs if (en.block_id == pw.block_id)), None):
            self._job_info_queue = [entry for entry in self._job_info_queue if (entry.job.block_id != pw.block_id)]
    self._register_analysis_job(pw.func_addr, pw)
    return [pw]
