private static MethodInfo ResolveMethod <TService>(Expression operation, out Action callback, out object[] args)
        {
            if (operation == null)
            {
                throw new ArgumentNullException("operation");
            }
            var lambda = operation as LambdaExpression;

            if (lambda == null)
            {
                throw new ArgumentException("LambdaExpression expected", "operation");
            }
            if (lambda.Parameters.Count != 1 || lambda.Parameters[0].Type != typeof(TService))
            {
                throw new ArgumentException("The lambda was expected to take a single argument of type " + typeof(TService));
            }
            var call = lambda.Body as MethodCallExpression;

            if (call == null || call.Object != lambda.Parameters[0])
            {
                throw new ArgumentNullException("Methods must invoked directly on the supplied service instance");
            }

            args = new object[call.Arguments.Count];
            object[]        argsCpy    = args; // used for capture
            ParameterInfo[] parameters = call.Method.GetParameters();
            callback = null;
            for (int i = 0; i < args.Length; i++)
            {
                if (parameters[i].ParameterType.IsByRef)
                {
                    FieldInfo field;
                    object    target;
                    if (!TryResolveField(call.Arguments[i], out field, out target))
                    {
                        throw new InvalidOperationException("Cannot guarantee ref/out behaviour due to expression complexity; consider simplifying the expression.");
                    }
                    args[i] = RpcUtils.IsRequestArgument(parameters[i]) ? field.GetValue(target) : null;
                    int iCpy = i; // for capture
                    callback += delegate { field.SetValue(target, argsCpy[iCpy]); };
                }
                else
                {
                    args[i] = Evaluate(call.Arguments[i]);
                }
            }
            return(call.Method);
        }