def stop(self, ends=None, forced=False):
        """
        Stops an ``NuMap`` instance. If the list of end tasks is specified *via*
        the "ends" argument a call to ``NuMap.stop`` will block the calling 
        thread and retrieve (discards) a maximum of 2 * stride of results. This 
        will stop  the worker pool and the threads which manage its input and 
        output queues respectively. 
                
        If the "ends" argument is not specified, but the "forced" argument is 
        the method does not block and the ``NuMap._stop`` has to be called after
        **all** pending results have been retrieved. Calling ``NuMap._stop`` with
        pending results **will** dead-lock.
        
        Either "ends" or "forced" has to be ``True``.
        
        Arguments:

          - ends (``list``) [default: ``None``] A list of task ids which are not
            consumed within the ``NuMap`` instance.
          - forced (``bool``) [default: ``False``] If "ends" is not ``None`` 
            this argument is ignored. If "ends" is ``None`` and "forced" is 
            ``True`` the ``NuMap`` instance will trigger *stopping mode*.
            
        """
        if self._started.isSet():
            if ends:
                self._stopping.set()
                # if _stopping is set the pool putter will notify the weave 
                # generator that no more new results are needed. The weave 
                # generator will stop _before_ getting the first result from 
                # task 0 in the next stride.
                log.debug('%s begins stopping routine' % self)
                to_do = ends[:] # if ends else ends
                # We continue this loop until all end tasks
                # have raised StopIteration this stops the pool
                while to_do:
                    for task in to_do:
                        try:
                            #for i in xrange(self.stride):
                            self.next(task=task)
                        except StopIteration:
                            to_do.remove(task)
                            log.debug('%s stopped task %s' % (self, task))
                            continue
                        except Exception, excp:
                            log.debug('%s task %s raised exception %s' % \
                                      (self, task, excp))
                # stop threads remove queues 
                self._stop()
                log.debug('%s finished stopping routine' % self)
            elif forced:
                self._stopping.set()
                log.debug('%s begins triggers stopping' % self)
                # someone has to retrieve results and call the _stop_managers
            else:
                # this is the default
                msg = '%s is started, but neither ends nor forced was set.' % \
                        self
                log.error(msg)
                raise RuntimeError(msg)