'Add an event :term:`subscriber` for the event stream
implied by the supplied ``iface`` interface.
The ``subscriber`` argument represents a callable object (or a
:term:`dotted Python name` which identifies a callable); it will be
called with a single object ``event`` whenever :app:`Pyramid` emits
an :term:`event` associated with the ``iface``, which may be an
:term:`interface` or a class or a :term:`dotted Python name` to a
global object representing an interface or a class.
Using the default ``iface`` value, ``None`` will cause the subscriber
to be registered for all event types. See :ref:`events_chapter` for
more information about events and subscribers.
Any number of predicate keyword arguments may be passed in
``**predicates``.  Each predicate named will narrow the set of
circumstances in which the subscriber will be invoked.  Each named
predicate must have been registered via
:meth:`pyramid.config.Configurator.add_subscriber_predicate` before it
can be used.  See :ref:`subscriber_predicates` for more information.
.. versionadded:: 1.4
The ``**predicates`` argument.'

@action_method
def add_subscriber(self, subscriber, iface=None, **predicates):

    dotted = self.maybe_dotted
    (subscriber, iface) = (dotted(subscriber), dotted(iface))
    if (iface is None):
        iface = (Interface,)
    if (not isinstance(iface, (tuple, list))):
        iface = (iface,)
    def register():
        predlist = self.get_predlist('subscriber')
        (order, preds, phash) = predlist.make(self, **predicates)
        derived_predicates = [self._derive_predicate(p) for p in preds]
        derived_subscriber = self._derive_subscriber(subscriber, derived_predicates)
        intr.update({'phash': phash, 'order': order, 'predicates': preds, 'derived_predicates': derived_predicates, 'derived_subscriber': derived_subscriber})
        self.registry.registerHandler(derived_subscriber, iface)
    intr = self.introspectable('subscribers', id(subscriber), self.object_description(subscriber), 'subscriber')
    intr['subscriber'] = subscriber
    intr['interfaces'] = iface
    self.action(None, register, introspectables=(intr,))
    return subscriber
