code: def addService(self, service, parentService=None):
          
          if parentService is not None:
              # Do check to ensure that parentService is a service of this job
              def check(services):
                  for jS in services:
                      if jS.service == parentService or check(jS.service._childServices):
                          return True
                  return False
              if not check(self._services):
                  raise JobException("Parent service is not a service of the given job")
              return parentService._addChild(service)
          else:
              if service._hasParent:
                  raise JobException("The service already has a parent service")
              service._hasParent = True
              jobService = ServiceJob(service)
              self._services.append(jobService)
              return jobService.rv()
docs: Add a service.
  
          The :func:`toil.job.Job.Service.start` method of the service will be called
          after the run method has completed but before any successors are run.
          The service's :func:`toil.job.Job.Service.stop` method will be called once
          the successors of the job have been run.
  
          Services allow things like databases and servers to be started and accessed
          by jobs in a workflow.
  
          :raises toil.job.JobException: If service has already been made the child of a job or another service.
          :param toil.job.Job.Service service: Service to add.
          :param toil.job.Job.Service parentService: Service that will be started before 'service' is
              started. Allows trees of services to be established. parentService must be a service
              of this job.
          :return: a promise that will be replaced with the return value from
              :func:`toil.job.Job.Service.start` of service in any successor of the job.
          :rtype: toil.job.Promise