<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def run(self, timeout=None, return_when=None, return_exceptions=None, ignore_empty=None):
 """ Executes the registered coroutines in the executor queue. Arguments: timeout (int/float):
 max execution timeout. No limit by default. return_exceptions (bool):
 in case of coroutine exception. return_when (str):
 sets when coroutine should be resolved. See `asyncio.wait`_ for supported values. ignore_empty (bool, optional):
 do not raise an exception if there are no coroutines to schedule are empty. Returns: asyncio.Future (tuple):
 two sets of Futures: ``(done, pending)`` Raises: ValueError: if there is no coroutines to schedule. RuntimeError: if executor is still running. TimeoutError: if execution takes more than expected. .. _asyncio.wait: https://docs.python.org/3/library/asyncio-task.html#asyncio.wait # noqa """

        # Only allow 1 concurrent execution
        if self.running:
            raise RuntimeError('paco: executor is already running')

        # Overwrite ignore empty behaviour, if explicitly defined
        ignore_empty = (self.ignore_empty if ignore_empty is None
                        else ignore_empty)

        # Check we have coroutines to schedule
        if len(self.pool) == 0:
            # If ignore empty mode enabled, just return an empty tuple
            if ignore_empty:
                return (tuple(), tuple())
            # Othwerise raise an exception
            raise ValueError('paco: pool of coroutines is empty')

        # Set executor state to running
        self.running = True

        # Configure return exceptions
        if return_exceptions is not None:
            self.return_exceptions = return_exceptions

        if return_exceptions is False and return_when is None:
            return_when = 'FIRST_EXCEPTION'

        if return_when is None:
            return_when = 'ALL_COMPLETED'

        # Trigger pre-execution event
        yield from self.observer.trigger('start', self)

        # Sequential coroutines execution
        if self.limit == 1:
            done, pending = yield from self._run_sequentially()

        # Concurrent execution based on configured limit
        if self.limit != 1:
            done, pending = yield from self._run_concurrently(
                timeout=timeout,
                return_when=return_when)

        # Reset internal state and queue
        self.running = False

        # Raise exception, if needed
        if self.return_exceptions is False and self.errors:
            err = self.errors[0]
            err.errors = self.errors[1:]
            raise err

        # Trigger pre-execution event
        yield from self.observer.trigger('finish', self)

        # Reset executor state to defaults after each execution
        self.reset()

        # Return resultant futures in two tuples
        return done, pending