def dispatch(self,stanza,session=None,direct=0):
        """ Main procedure that performs XMPP stanza recognition and calling apppropriate handlers for it.
            Called internally. """
        if not session: session=self
        session.Stream._mini_dom=None
        name=stanza.getName()

        if not direct and self._owner._route:
            if name == 'route':
                if stanza.getAttr('error') == None:
                    if len(stanza.getChildren()) == 1:
                        stanza = stanza.getChildren()[0]
                        name=stanza.getName()
                    else:
                        for each in stanza.getChildren():
                            self.dispatch(each,session,direct=1)
                        return
            elif name == 'presence':
                return
            elif name in ('features','bind'):
                pass
            else:
                raise UnsupportedStanzaType(name)

        if name=='features': session.Stream.features=stanza

        xmlns=stanza.getNamespace()
        if not self.handlers.has_key(xmlns):
            self.DEBUG("Unknown namespace: " + xmlns,'warn')
            xmlns='unknown'
        if not self.handlers[xmlns].has_key(name):
            self.DEBUG("Unknown stanza: " + name,'warn')
            name='unknown'
        else:
            self.DEBUG("Got %s/%s stanza"%(xmlns,name), 'ok')

        if stanza.__class__.__name__=='Node': stanza=self.handlers[xmlns][name][type](node=stanza)

        typ=stanza.getType()
        if not typ: typ=''
        stanza.props=stanza.getProperties()
        ID=stanza.getID()

        session.DEBUG("Dispatching %s stanza with type->%s props->%s id->%s"%(name,typ,stanza.props,ID),'ok')

        list=['default']                                                     # we will use all handlers:
        if self.handlers[xmlns][name].has_key(typ): list.append(typ)                # from very common...
        for prop in stanza.props:
            if self.handlers[xmlns][name].has_key(prop): list.append(prop)
            if typ and self.handlers[xmlns][name].has_key(typ+prop): list.append(typ+prop)  # ...to very particular

        chain=self.handlers[xmlns]['default']['default']
        for key in list:
            if key: chain = chain + self.handlers[xmlns][name][key]

        output=''
        if session._expected.has_key(ID):
            user=0
            if type(session._expected[ID])==type(()):
                cb,args=session._expected[ID]
                session.DEBUG("Expected stanza arrived. Callback %s(%s) found!"%(cb,args),'ok')
                try: cb(session,stanza,**args)
                except Exception, typ:
                    if typ.__class__.__name__<>'NodeProcessed': raise
            else:
                session.DEBUG("Expected stanza arrived!",'ok')
                session._expected[ID]=stanza
        else: user=1
        for handler in chain:
            if user or handler['system']:
                try:
                    handler['func'](session,stanza)
                except Exception, typ:
                    if typ.__class__.__name__<>'NodeProcessed':
                        self._pendingExceptions.insert(0, sys.exc_info())
                        return
                    user=0
        if user and self._defaultHandler: self._defaultHandler(session,stanza)
 Main procedure that performs XMPP stanza recognition and calling apppropriate handlers for it.
            Called internally. 
chrome-cordova/gcmServer/xmpp/dispatcher.py