private static void ValidateArgumentTypes(XzaarMethodBase method, ExpressionType nodeKind, ref ReadOnlyCollection <XzaarExpression> arguments)
        {
            // Debug.Assert(nodeKind == ExpressionType.Invoke || nodeKind == ExpressionType.Call || nodeKind == ExpressionType.Dynamic || nodeKind == ExpressionType.New);

            XzaarParameterInfo[] pis = GetParametersForValidation(method, nodeKind);

            ValidateArgumentCount(method, nodeKind, arguments.Count, pis);

            XzaarExpression[] newArgs = null;
            for (int i = 0, n = pis.Length; i < n; i++)
            {
                XzaarExpression    arg = arguments[i];
                XzaarParameterInfo pi  = pis[i];
                arg = ValidateOneArgument(method, nodeKind, arg, pi);

                if (newArgs == null && arg != arguments[i])
                {
                    newArgs = new XzaarExpression[arguments.Count];
                    for (int j = 0; j < i; j++)
                    {
                        newArgs[j] = arguments[j];
                    }
                }
                if (newArgs != null)
                {
                    newArgs[i] = arg;
                }
            }
            if (newArgs != null)
            {
                arguments = new TrueReadOnlyCollection <XzaarExpression>(newArgs);
            }
        }
        private static XzaarParameterInfo[] GetParametersForValidation(XzaarMethodBase method, ExpressionType nodeKind)
        {
            if (nodeKind != ExpressionType.Dynamic)
            {
                return(method.GetParameters());
            }
            var methodParam = method.GetParameters();
            var param       = new XzaarParameterInfo[methodParam.Length - 1];

            Array.Copy(methodParam, 1, param, 0, param.Length);
            return(param);
        }
        private static XzaarExpression ValidateOneArgument(XzaarMethodBase method, ExpressionType nodeKind, XzaarExpression arg, XzaarParameterInfo pi)
        {
            // this is most likely an 'Any' object
            if (pi == null)
            {
                return(arg);
            }

            RequiresCanRead(arg, "arguments");

            var pType = pi.ParameterType;

            if (pType.IsByRef)
            {
                pType = pType.GetElementType();
            }
            // XzaarTypeUtils.ValidateType(pType);
            if (!XzaarTypeUtils.AreReferenceAssignable(pType, arg.Type))
            {
                if (!TryQuote(pType, ref arg))
                {
                    // Throw the right error for the node we were given
                    switch (nodeKind)
                    {
                    case ExpressionType.New:
                        throw new InvalidOperationException();

                    // throw Error.ExpressionTypeDoesNotMatchConstructorParameter(arg.Type, pType);
                    case ExpressionType.Invoke:
                        throw new InvalidOperationException();

                    // throw Error.ExpressionTypeDoesNotMatchParameter(arg.Type, pType);
                    case ExpressionType.Dynamic:
                    case ExpressionType.Call:
                        throw new InvalidOperationException();

                    // throw Error.ExpressionTypeDoesNotMatchMethodParameter(arg.Type, pType, method);
                    default:
                        throw new InvalidOperationException();
                        // throw ContractUtils.Unreachable;
                    }
                }
            }
            return(arg);
        }