def disconnect(self, forced=False):
if not self.connected:<EOL><INDENT>self.log.error('<STR_LIT>' % self)<EOL>raise PiperError('<STR_LIT>' % self)<EOL><DEDENT>elif self.started:<EOL><INDENT>self.log.error('<STR_LIT>' % self)<EOL>raise PiperError('<STR_LIT>' % self)<EOL><DEDENT>elif hasattr(self.imap, '<STR_LIT>') and self.imap._started.isSet():<EOL><INDENT>self.log.error('<STR_LIT>' % self)<EOL>raise PiperError('<STR_LIT>' % self)<EOL><DEDENT>else:<EOL><INDENT>if hasattr(self.imap, '<STR_LIT>'):<EOL><INDENT>if self.imap._tasks == []:<EOL><INDENT>pass<EOL><DEDENT>elif self.imap_tasks[-<NUM_LIT:1>].task == len(self.imap._tasks) - <NUM_LIT:1>:<EOL><INDENT>self.imap.pop_task(number=self.spawn)<EOL><DEDENT>elif forced:<EOL><INDENT>self.imap.pop_task(number=True)<EOL><DEDENT>else:<EOL><INDENT>msg = '<STR_LIT>' %self<EOL>self.log.error(msg)<EOL>raise PiperError(msg)<EOL><DEDENT><DEDENT>self.log.debug('<STR_LIT>' % (self, self.inbox))<EOL>self.imap_tasks = []<EOL>self.inbox = None<EOL>self.outbox = None<EOL>self.connected = False<EOL><DEDENT>
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.