<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def start(self, pipeline, return_task=True, countdown=None, eta=None):
 """Starts a pipeline. Args: pipeline: Pipeline instance to run. return_task: When True, do not submit the task to start the pipeline but instead return it for someone else to enqueue. countdown: Time in seconds into the future that this Task should execute. Defaults to zero. eta: A datetime.datetime specifying the absolute time at which the task should be executed. Must not be specified if 'countdown' is specified. This may be timezone-aware or timezone-naive. If None, defaults to now. For pull tasks, no worker will be able to lease this task before the time indicated by eta. Returns: The task to start this pipeline if return_task was True. Raises: PipelineExistsError if the pipeline with the given ID already exists. """

    # Adjust all pipeline output keys for this Pipeline to be children of
    # the _PipelineRecord, that way we can write them all and submit in a
    # single transaction.
    for name, slot in pipeline.outputs._output_dict.iteritems():
      slot.key = db.Key.from_path(
          *slot.key.to_path(), **dict(parent=pipeline._pipeline_key))

    _, output_slots, params_text, params_blob = _generate_args(
        pipeline, pipeline.outputs, self.queue_name, self.base_path)

    @db.transactional(propagation=db.INDEPENDENT)
    def txn():
      pipeline_record = db.get(pipeline._pipeline_key)
      if pipeline_record is not None:
        raise PipelineExistsError(
            'Pipeline with idempotence key "%s" already exists; params=%s' %
            (pipeline._pipeline_key.name(),
             _short_repr(pipeline_record.params)))

      entities_to_put = []
      for name, slot in pipeline.outputs._output_dict.iteritems():
        entities_to_put.append(_SlotRecord(
            key=slot.key,
            root_pipeline=pipeline._pipeline_key))

      entities_to_put.append(_PipelineRecord(
          key=pipeline._pipeline_key,
          root_pipeline=pipeline._pipeline_key,
          is_root_pipeline=True,
          # Bug in DB means we need to use the storage name here,
          # not the local property name.
          params=params_text,
          params_blob=params_blob,
          start_time=self._gettime(),
          class_path=pipeline._class_path,
          max_attempts=pipeline.max_attempts))

      entities_to_put.extend(_PipelineContext._create_barrier_entities(
          pipeline._pipeline_key,
          pipeline._pipeline_key,
          _BarrierRecord.FINALIZE,
          output_slots))

      db.put(entities_to_put)

      task = taskqueue.Task(
          url=self.pipeline_handler_path,
          params=dict(pipeline_key=pipeline._pipeline_key),
          headers={'X-Ae-Pipeline-Key': pipeline._pipeline_key},
          target=pipeline.target,
          countdown=countdown,
          eta=eta)
      if return_task:
        return task
      task.add(queue_name=self.queue_name, transactional=True)

    task = txn()
    # Immediately mark the output slots as existing so they can be filled
    # by asynchronous pipelines or used in test mode.
    for output_slot in pipeline.outputs._output_dict.itervalues():
      output_slot._exists = True
    return task