'Process an array of calls, and return an array of
results. Calls should be structs of the form {\'methodName\':
string, \'params\': array}. Each result will either be a
single-item array containing the result value, or a struct of
the form {\'faultCode\': int, \'faultString\': string}. This is
useful when you need to make lots of small calls without lots
of round trips.
@param array calls  An array of call requests
@return array result  An array of results'

def multicall(self, calls):

    remaining_calls = calls[:]
    callbacks = []
    results = []
    def multi(remaining_calls=remaining_calls, callbacks=callbacks, results=results):
        if callbacks:
            try:
                value = callbacks[0]()
            except RPCError as exc:
                value = {'faultCode': exc.code, 'faultString': exc.text}
            except:
                info = sys.exc_info()
                errmsg = ('%s:%s' % (info[0], info[1]))
                value = {'faultCode': Faults.FAILED, 'faultString': ('FAILED:    ' + errmsg)}
            if (value is not NOT_DONE_YET):
                callbacks.pop(0)
                results.append(value)
        while ((not callbacks) and remaining_calls):
            call = remaining_calls.pop(0)
            name = call.get('methodName', None)
            params = call.get('params', [])
            try:
                if (name is None):
                    raise RPCError(Faults.INCORRECT_PARAMETERS, 'No    methodName')
                if (name == 'system.multicall'):
                    raise RPCError(Faults.INCORRECT_PARAMETERS, 'Recursive    system.multicall    forbidden')
                root = AttrDict(self.namespaces)
                value = traverse(root, name, params)
            except RPCError as exc:
                value = {'faultCode': exc.code, 'faultString': exc.text}
            except:
                info = sys.exc_info()
                errmsg = ('%s:%s' % (info[0], info[1]))
                value = {'faultCode': Faults.FAILED, 'faultString': ('FAILED:    ' + errmsg)}
            if isinstance(value, types.FunctionType):
                callbacks.append(value)
            else:
                results.append(value)
        if (callbacks or remaining_calls):
            return NOT_DONE_YET
        else:
            return results
    multi.delay = 0.05
    value = multi()
    if (value is NOT_DONE_YET):
        return multi
    else:
        return value
