private static bool IsCompatible(XzaarMethodBase m, XzaarExpression[] args)
        {
            var parms = m.GetParameters();

            if (parms.Length != args.Length)
            {
                return(false);
            }
            for (var i = 0; i < args.Length; i++)
            {
                var arg = args[i];
                //ContractUtils.RequiresNotNull(arg, "argument");
                var argType = arg.Type;
                var pType   = parms[i].ParameterType;
                if (pType.IsByRef)
                {
                    pType = pType.GetElementType();
                }
                if (!XzaarTypeUtils.AreReferenceAssignable(pType, argType)) // &&  !(XzaarTypeUtils.IsSameOrSubclass(typeof(LambdaExpression), pType) && pType.IsAssignableFrom(arg.GetType()))
                {
                    return(false);
                }
            }
            return(true);
        }
        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);
        }
        public static IfElseExpression IfElse(XzaarExpression test, XzaarExpression ifTrue, XzaarExpression ifFalse, XzaarType type)
        {
            RequiresCanRead(test, "test");
            RequiresCanRead(ifTrue, "ifTrue");
            RequiresCanRead(ifFalse, "ifFalse");

            if (test.Type != XzaarBaseTypes.Boolean)
            {
                // throw Error.ArgumentMustBeBoolean();
                throw new InvalidOperationException("Argument must be boolean");
            }

            if (type != XzaarBaseTypes.Void)
            {
                if (!XzaarTypeUtils.AreReferenceAssignable(type, ifTrue.Type) ||
                    !XzaarTypeUtils.AreReferenceAssignable(type, ifFalse.Type))
                {
                    throw new InvalidOperationException("Argument types must match");
                }
            }

            return(IfElseExpression.Make(test, ifTrue, ifFalse, type));
        }