docs: def _create_new_jobs(self, job, successor, new_block_id, new_call_stack):
          """
          Create a list of new VFG jobs for the successor state.
  
          :param VFGJob job:                 The VFGJob instance.
          :param SimState successor: The succeeding state.
          :param BlockID new_block_id:       Block ID for the new VFGJob
          :param new_call_stack:             The new callstack.
          :return:                           A list of newly created VFG jobs.
          :rtype:                            list
          """
  
          # TODO: basic block stack is probably useless
  
          jumpkind = successor.history.jumpkind
          stmt_idx = successor.scratch.stmt_idx
          ins_addr = successor.scratch.ins_addr
          # Make a copy of the state in case we use it later
          successor_state = successor.copy()
          successor_addr = successor_state.solver.eval(successor_state.ip)
  
          new_jobs = [ ]
  
          if jumpkind == "Ijk_FakeRet":
              assert job.is_call_jump
  
              # This is the default "fake" return successor generated at each call, if and only if the target function
              # returns.
  
              # if the call is skipped (for whatever reason, like we reached the interfunction tracing limit), we use
              # this FakeRet successor as the final state of the function. Otherwise we save the FakeRet state in case the
              # callee does not return normally, but don't process them right away.
  
              # Clear the useless values (like return addresses, parameters) on stack if needed
              if self._cfg is not None:
                  current_function = self.kb.functions.function(job.call_target)
                  if current_function is not None:
                      sp_difference = current_function.sp_delta
                  else:
                      sp_difference = 0
                  reg_sp_offset = successor_state.arch.sp_offset
                  reg_sp_expr = successor_state.registers.load(reg_sp_offset) + sp_difference
                  successor_state.registers.store(successor_state.arch.sp_offset, reg_sp_expr)
  
                  # Clear the return value with a TOP
                  top_si = successor_state.solver.TSI(successor_state.arch.bits)
                  successor_state.registers.store(successor_state.arch.ret_offset, top_si)
  
              if job.call_skipped:
  
                  # TODO: Make sure the return values make sense
                  #if self.project.arch.name == 'X86':
                  #    successor_state.regs.eax = successor_state.solver.BVS('ret_val', 32, min=0, max=0xffffffff, stride=1)
  
                  new_job = VFGJob(successor_addr,
                                   successor_state,
                                   self._context_sensitivity_level,
                                   block_id=new_block_id,
                                   jumpkind='Ijk_Ret',
                                   call_stack=new_call_stack,
                                   src_block_id=job.block_id,
                                   src_exit_stmt_idx=stmt_idx,
                                   src_ins_addr=ins_addr,
                                   )
  
                  new_jobs.append(new_job)
                  assert isinstance(self._task_stack[-2], FunctionAnalysis)
                  self._task_stack[-2].jobs.append(new_job)
                  job.dbg_exit_status[successor] = "Pending"
  
              else:
                  self._pending_returns[new_block_id] = PendingJob(new_block_id, successor_state, new_call_stack,
                                                                   job.block_id, stmt_idx, ins_addr)
                  job.dbg_exit_status[successor] = "Pending"
  
          else:
              if sim_options.ABSTRACT_MEMORY in successor.options:
                  if self._is_call_jumpkind(successor.history.jumpkind):
                      # If this is a call, we create a new stack address mapping
                      reg_sp_si = self._create_stack_region(successor_state, successor_addr)
  
                      # Save the new sp register
                      new_reg_sp_expr = successor_state.solver.ValueSet(successor_state.arch.bits,
                                                                         'global',
                                                                         0,
                                                                         reg_sp_si
                                                                         )
                      successor_state.regs.sp = new_reg_sp_expr
  
                  elif successor.history.jumpkind == "Ijk_Ret":
                      # Remove the existing stack address mapping
                      # FIXME: Now we are assuming the sp is restored to its original value
                      reg_sp_expr = successor_state.regs.sp
  
                      if isinstance(reg_sp_expr._model_vsa, claripy.vsa.StridedInterval):
                          reg_sp_si = reg_sp_expr._model_vsa
                          reg_sp_val = reg_sp_si.min
                      elif isinstance(reg_sp_expr._model_vsa, claripy.vsa.ValueSet):
                          reg_sp_si = next(iter(reg_sp_expr._model_vsa.items()))[1]
                          reg_sp_val = reg_sp_si.min
                          # TODO: Finish it!
  
              new_job = VFGJob(successor_addr,
                               successor_state,
                               self._context_sensitivity_level,
                               block_id=new_block_id,
                               jumpkind=successor_state.history.jumpkind,
                               call_stack=new_call_stack,
                               src_block_id=job.block_id,
                               src_exit_stmt_idx=stmt_idx,
                               src_ins_addr=ins_addr,
                               )
  
              if successor.history.jumpkind == 'Ijk_Ret':
                  # it's returning to the return site
  
                  # save the state as a final state of the function that we are returning from
                  if self._record_function_final_states:
                      # key of the function that we are returning from
                      source_function_key = FunctionKey.new(job.func_addr,
                                                            job.call_stack_suffix
                                                            )
                      self._save_function_final_state(source_function_key, job.func_addr, successor_state)
  
                  # TODO: add an assertion that requires the returning target being the same as the return address we
                  # TODO: stored before
  
                  current_task = self._top_task
                  if current_task.call_analysis is not None:
                      current_task.call_analysis.add_final_job(new_job)
  
                      job.dbg_exit_status[successor] = "Appended to the call analysis task"
                  else:
                      job.dbg_exit_status[successor] = "Discarded (no call analysis task)"
  
              else:
                  if self._is_call_jumpkind(successor.history.jumpkind):
                      # create a function analysis task
                      # TODO: the return address
                      task = FunctionAnalysis(new_job.addr, None)
                      self._task_stack.append(task)
                      # link it to the call analysis
                      job.call_task.register_function_analysis(task)
  
                  else:
                      task = self._top_task
  
                  # register the job to the function task
                  task.jobs.append(new_job)
                  # insert the new job into the new job array
                  new_jobs.append(new_job)
  
                  job.dbg_exit_status[successor] = "Appended"
  
          if not job.is_call_jump or jumpkind != "Ijk_FakeRet":
              new_target = (new_block_id, jumpkind)
          else:
              new_target = (new_block_id, "Ijk_FakeRet")  # This is the fake return!
          self._exit_targets[job.call_stack_suffix + (job.addr,)].append(new_target)
  
          return new_jobs