async def stop(self):
        if self.stopped:
            return
        self._logger.debug("Stopping task %s", self.name)
        if self._finalizer is not None:
            try:
                result = self._finalizer(self)
                if inspect.isawaitable(result):
                    await result
            except:
                self._logger.exception("Error running finalizer for task %s",
                                       self.name)
        elif self.task is not None:
            self.task.cancel()
        tasks = []
        if self.task is not None:
            tasks.append(self.task)
        tasks.extend(x.task for x in self.subtasks)
        finished = asyncio.gather(*tasks, return_exceptions=True)
        outcomes = []
        try:
            outcomes = await asyncio.wait_for(finished, timeout=self._stop_timeout)
        except asyncio.TimeoutError as err:
            try:
                outcomes = await finished
            except asyncio.CancelledError:
                pass
            raise err
        finally:
            self.stopped = True
            for outcome in outcomes:
                if isinstance(outcome, Exception) and not isinstance(outcome, asyncio.CancelledError):
                    self._logger.error(outcome)
            if self in self._loop.tasks:
                self._loop.tasks.remove(self)