Returns the next result for the given **task**. Defaults to ``0``, which
        is the first **task**. If multiple chained tasks are evaluated then the
        next method of only the last should be called directly. 
                
        Arguments:
        
          - timeout (``float``) Number of seconds to wait until a 
            ``TimeoutError`` is raised.
          - task (``int``) id of the task from the ``NuMap`` instance
          - block (``bool``) if ``True`` call will block until result is 
            available

def next(self, timeout=None, task=0, block=True):
        """
        Returns the next result for the given **task**. Defaults to ``0``, which
        is the first **task**. If multiple chained tasks are evaluated then the
        next method of only the last should be called directly. 
                
        Arguments:
        
          - timeout (``float``) Number of seconds to wait until a 
            ``TimeoutError`` is raised.
          - task (``int``) id of the task from the ``NuMap`` instance
          - block (``bool``) if ``True`` call will block until result is 
            available
            
        """
        # check if any result is expected (started and not finished)
        if not self._started.isSet():
            log.debug('%s has not yet been started' % self)
            raise RuntimeError('%s has not yet been started' % self)
        elif self._task_finished[task].isSet():
            log.debug('%s has finished task %s' % (self, task))
            raise StopIteration

        # try to get a result
        try:
            log.debug('%s waits for a result: ordered %s, task %s' % \
                      (self, self.ordered, task))
            if self.ordered:
                _got_next = \
                    self._next_available[task].get(timeout=timeout, block=block)
                log.debug('%s has been released for task: %s' % (self, task))
                result = self._task_results[task].get()
            else:
                result = \
                    self._task_results[task].get(timeout=timeout, block=block)
        except Empty:
            self._task_next_lock[task].acquire()
            log.debug('%s timeout for result: ordered %s, task %s' % \
                      (self, self.ordered, task))
            # the threads might have switched between the exception and the 
            # lock.acquire during this switch several items could have been 
            # submited to the queue if one of them is the one we are waiting 
            # for we get it here immediately, but lock the pool getter not to
            # submit more results.
            try:
                if self.ordered:
                    _got_next = self._next_available[task].get(block=False)
                    log.debug('%s has been released for task: %s' % \
                              (self, task))
                    result = self._task_results[task].get()
                else:
                    result = self._task_results[task].get(block=False)
            except Empty:
                if self.skip:
                    self._next_skipped[task] += 1
                    self._pool_semaphore.release()
                self._task_next_lock[task].release()
                raise TimeoutError('%s timeout for result: ordered %s, task %s' % \
                                   (self, self.ordered, task))
        log.debug('%s got a result: ordered %s, task %s, %s' % \
                  (self, self.ordered, task, result))
        # return or raise the result
        index, is_valid, real_result = result
        if index == 'stop':
            # got the stop sentinel
            self._task_finished[task].set()
            log.debug('%s releases semaphore after StopIteration of task %s' % \
                      (self, task))
            self._pool_semaphore.release()
            log.debug('%s has finished task %s for the first time' % \
                      (self, task))
            raise StopIteration
        if task in self._tasks_tracked:
            self._tasks_tracked[task][index] = real_result
        if is_valid:
            log.debug('%s returns %s for task %s' % (self, index, task))
            self._pool_semaphore.release()
            return real_result
        else:
            log.debug('%s raises %s for task %s' % (self, index, task))
            self._pool_semaphore.release()
            raise real_result