Disconnects the ``Piper`` instance from its upstream ``Pipers`` or 
        input data if the ``Piper`` is the input node of a pipeline.
        
        Arguments:
        
          - forced(``bool``) [default: ``False``] If ``True`` the ``Piper`` will
            try to forcefully remove all tasks (including the spawned ones) from
            the ``NuMap`` instance.

def disconnect(self, forced=False):
        """
        Disconnects the ``Piper`` instance from its upstream ``Pipers`` or 
        input data if the ``Piper`` is the input node of a pipeline.
        
        Arguments:
        
          - forced(``bool``) [default: ``False``] If ``True`` the ``Piper`` will
            try to forcefully remove all tasks (including the spawned ones) from
            the ``NuMap`` instance.
             
        """
        if not self.connected:
            self.log.error('Piper %s is not connected and cannot be disconnected' % self)
            raise PiperError('Piper %s is not connected and cannot be disconnected' % self)
        elif self.started:
            self.log.error('Piper %s is started and cannot be disconnected (stop first)' % self)
            raise PiperError('Piper %s is started and cannot be disconnected (stop first)' % self)
        elif hasattr(self.imap, '_started') and self.imap._started.isSet():
            self.log.error('Piper %s cannot disconnect as its NuMap is started' % self)
            raise PiperError('Piper %s cannot disconnect as its NuMap is started' % self)
        else:
            # connected and not started
            if hasattr(self.imap, '_started'):
                if self.imap._tasks == []:
                    # fully stopped
                    pass
                elif self.imap_tasks[-1].task == len(self.imap._tasks) - 1:
                    # the last task of this piper is the last task in the NuMap
                    self.imap.pop_task(number=self.spawn)
                elif forced:
                    # removes all tasks from the NuMap can be called multiple 
                    # times.
                    self.imap.pop_task(number=True)
                else:
                    msg = 'Piper %s is not the last Piper added to the NuMap' % \
                            self
                    self.log.error(msg)
                    raise PiperError(msg)
            self.log.debug('Piper %s disconnected from %s' % (self, self.inbox))
            self.imap_tasks = []
            self.inbox = None
            self.outbox = None
            self.connected = False