':param Job job: the job to add
:param bool replace_existing: ``True`` to use update_job() in case the job already exists in the store
:param bool wakeup: ``True`` to wake up the scheduler after adding the job'

def _real_add_job(self, job, jobstore_alias, replace_existing, wakeup):

    replacements = {}
    for (key, value) in six.iteritems(self._job_defaults):
        if (not hasattr(job, key)):
            replacements[key] = value
    if (not hasattr(job, 'next_run_time')):
        now = datetime.now(self.timezone)
        replacements['next_run_time'] = job.trigger.get_next_fire_time(None, now)
    job._modify(**replacements)
    store = self._lookup_jobstore(jobstore_alias)
    try:
        store.add_job(job)
    except ConflictingIdError:
        if replace_existing:
            store.update_job(job)
        else:
            raise
    job._jobstore_alias = jobstore_alias
    event = JobEvent(EVENT_JOB_ADDED, job.id, jobstore_alias)
    self._dispatch_event(event)
    self._logger.info('Added    job    "%s"    to    job    store    "%s"', job.name, jobstore_alias)
    if wakeup:
        self.wakeup()
