'Wrap Pika\'s Channel method to make it return a Deferred that fires
when the method completes and errbacks if the channel gets closed. If
the original method\'s callback would receive more than one argument, the
Deferred fires with a tuple of argument values.'

def __wrap_channel_method(self, name):

    method = getattr(self.__channel, name)
    @functools.wraps(method)
    def wrapped(*args, **kwargs):
        if self.__closed:
            return defer.fail(self.__closed)
        d = defer.Deferred()
        self.__calls.add(d)
        d.addCallback(self.__clear_call, d)
        def single_argument(*args):
            '\n                                                                Make    sure    that    the    deferred    is    called    with    a    single    argument.\n                                                                In    case    the    original    callback    fires    with    more    than    one,    convert\n                                                                to    a    tuple.\n                                                                '
            if (len(args) > 1):
                d.callback(tuple(args))
            else:
                d.callback(*args)
        kwargs['callback'] = single_argument
        try:
            method(*args, **kwargs)
        except:
            return defer.fail()
        return d
    return wrapped
