Adds a ``Piper`` instance to this ``Dagger``, but only if the ``Piper`` 
        is not already there. Optionally creates a new ``Piper`` if the "piper"
        argument is valid for the ``Piper`` constructor. Returns a ``tuple``
        (new_piper_created, piper_instance) indicating whether a new ``Piper`` 
        has been created and the instance of the added ``Piper``. Optionally 
        takes "branch" and "xtra" arguments for the topological node in the 
        graph.
        
        Arguments:
        
          - piper(``Piper``, ``Worker`` or id(``Piper``)) ``Piper`` instance or 
            object which will be converted to a ``Piper`` instance.
          - create(``bool``) [default: ``True``] Should a new ``Piper`` be 
            created if "piper" cannot be resolved in this ``Dagger``?
          - xtra(``dict``) [default: ``None``] Dictionary of  ``graph.Node``  
            properties.

def add_piper(self, piper, xtra=None, create=True, branch=None):
        """
        Adds a ``Piper`` instance to this ``Dagger``, but only if the ``Piper`` 
        is not already there. Optionally creates a new ``Piper`` if the "piper"
        argument is valid for the ``Piper`` constructor. Returns a ``tuple``
        (new_piper_created, piper_instance) indicating whether a new ``Piper`` 
        has been created and the instance of the added ``Piper``. Optionally 
        takes "branch" and "xtra" arguments for the topological node in the 
        graph.
        
        Arguments:
        
          - piper(``Piper``, ``Worker`` or id(``Piper``)) ``Piper`` instance or 
            object which will be converted to a ``Piper`` instance.
          - create(``bool``) [default: ``True``] Should a new ``Piper`` be 
            created if "piper" cannot be resolved in this ``Dagger``?
          - xtra(``dict``) [default: ``None``] Dictionary of  ``graph.Node``  
            properties.
        
        """
        self.log.debug('%s trying to add piper %s' % (repr(self), piper))
        piper = (self.resolve(piper, forgive=True) or piper)
        if not isinstance(piper, Piper):
            if create:
                try:
                    piper = Piper(piper)
                except PiperError:
                    self.log.error('%s cannot resolve or create a piper from %s' % \
                                   (repr(self), repr(piper)))
                    raise DaggerError('%s cannot resolve or create a piper from %s' % \
                                      (repr(self), repr(piper)))
            else:
                self.log.error('%s cannot resolve a piper from %s' % \
                               (repr(self), repr(piper)))
                raise DaggerError('%s cannot resolve a piper from %s' % \
                                  (repr(self), repr(piper)))
        new_piper_created = self.add_node(piper, xtra, branch)
        if new_piper_created:
            self.log.debug('%s added piper %s' % (repr(self), piper))
        return (new_piper_created, piper)