'This is the primary high-level API for sending messages via AMP.  Invoke it
with a command and appropriate arguments to send a message to this
connection\'s peer.
@param commandType: a subclass of Command.
@type commandType: L{type}
@param a: Positional (special) parameters taken by the command.
Positional parameters will typically not be sent over the wire.  The
only command included with AMP which uses positional parameters is
L{ProtocolSwitchCommand}, which takes the protocol that will be
switched to as its first argument.
@param kw: Keyword arguments taken by the command.  These are the
arguments declared in the command\'s \'arguments\' attribute.  They will
be encoded and sent to the peer as arguments for the L{commandType}.
@return: If L{commandType} has a C{requiresAnswer} attribute set to
L{False}, then return L{None}.  Otherwise, return a L{Deferred} which
fires with a dictionary of objects representing the result of this
call.  Additionally, this L{Deferred} may fail with an exception
representing a connection failure, with L{UnknownRemoteError} if the
other end of the connection fails for an unknown reason, or with any
error specified as a key in L{commandType}\'s C{errors} dictionary.'

def callRemote(self, commandType, *a, **kw):

    try:
        co = commandType(*a, **kw)
    except:
        return fail()
    return co._doCommand(self)
