<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def join(self):
 """ Wait for all task to finish """

        pending = set()
        exceptions = set()
        while len(self._tasks) > 0 or len(pending) > 0:
            while len(self._tasks) > 0 and len(pending) < self._concurrency:
                task, args, kwargs = self._tasks.pop(0)
                pending.add(task(*args, **kwargs))
            (done, pending) = yield from asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED)
            for task in done:
                if task.exception():
                    exceptions.add(task.exception())
        if len(exceptions) > 0:
            raise exceptions.pop()