'Execute an API callback, based on specificity.
The API callback that is executed is chosen based on the combination
of the provided JID and node:
JID   | node  | Handler
Given | Given | Node handler
Given | None  | JID handler
None  | None  | Global handler
A node handler is responsible for servicing a single node at a single
JID, while a JID handler may respond for any node at a given JID, and
the global handler will answer to any JID+node combination.
Handlers should check that the JID ``ifrom`` is authorized to perform
the desired action.
:param string ctype: The name of the API to use.
:param string op: The API operation to perform.
:param JID jid: Optionally provide specific JID.
:param string node: Optionally provide specific node.
:param JID ifrom: Optionally provide the requesting JID.
:param tuple args: Optional positional arguments to the handler.'

def run(self, ctype, op, jid=None, node=None, ifrom=None, args=None):

    self._setup(ctype, op)
    if (not jid):
        jid = self.xmpp.boundjid
    elif (jid and (not isinstance(jid, JID))):
        jid = JID(jid)
    elif (jid == JID('')):
        jid = self.xmpp.boundjid
    if (node is None):
        node = ''
    if self.xmpp.is_component:
        if self.settings[ctype].get('component_bare', False):
            jid = jid.bare
        else:
            jid = jid.full
    elif self.settings[ctype].get('client_bare', False):
        jid = jid.bare
    else:
        jid = jid.full
    jid = JID(jid)
    handler = self._handlers[ctype][op]['node'].get((jid, node), None)
    if (handler is None):
        handler = self._handlers[ctype][op]['jid'].get(jid, None)
    if (handler is None):
        handler = self._handlers[ctype][op].get('global', None)
    if handler:
        try:
            return handler(jid, node, ifrom, args)
        except TypeError:
            return handler(jid, node, args)
