internal static MethodData FindMethod(this ArgumentData target, string methodName, Type[] typeArgs,
                                              IList <ArgumentData> args, IEnumerable <Type> knownTypes, bool staticAccess)
        {
            var type = target.Type;
            const MemberFlags flags = MemberFlags.Public | MemberFlags.Static | MemberFlags.Instance;
            var methods             = new List <MethodInfo>();

            foreach (var info in type.GetMethodsEx(flags))
            {
                if (info.Name == methodName && info.IsStatic == staticAccess)
                {
                    methods.Add(info);
                }
            }
            if (!staticAccess)
            {
                methods.AddRange(GetExtensionsMethods(methodName, knownTypes));
            }
            var method = FindBestMethod(target, methods, args, typeArgs);

            if (method == null)
            {
                throw BindingExceptionManager.InvalidBindingMember(type, methodName);
            }
            return(method);
        }
        internal static MethodData FindIndexer(this ArgumentData target, IList <ArgumentData> args, bool staticAccess)
        {
            var type    = target.Type;
            var methods = new List <MethodInfo>();

            foreach (var property in type.GetPropertiesEx(MemberFlags.Public | MemberFlags.Instance))
            {
                if (property.GetIndexParameters().Length == args.Count)
                {
                    var m = property.GetGetMethod(true);
                    if (m != null && m.IsStatic == staticAccess)
                    {
                        methods.Add(m);
                    }
                }
            }


            var method = FindBestMethod(target, methods, args, Empty.Array <Type>());

            if (method == null)
            {
                throw BindingExceptionManager.InvalidBindingMember(type, "Item[]");
            }
            return(method);
        }
        internal static MemberInfo FindPropertyOrField(this Type type, string memberName, bool staticAccess, bool throwOnError)
        {
            var          flags    = MemberFlags.Public | (staticAccess ? MemberFlags.Static : MemberFlags.Instance);
            PropertyInfo property = type.GetPropertyEx(memberName, flags);

            if (property != null)
            {
                return(property);
            }
            FieldInfo field = type.GetFieldEx(memberName, flags);

            if (field == null && throwOnError)
            {
                throw BindingExceptionManager.InvalidBindingMember(type, memberName);
            }
            return(field);
        }
        private static MethodData TryInferGenericMethod(MethodInfo method, IList <ArgumentData> args)
        {
            bool hasUnresolved;
            var  genericMethod = TryInferGenericMethod(method, args, out hasUnresolved);

            if (genericMethod == null)
            {
                return(null);
            }
            if (hasUnresolved)
            {
                return(new MethodData(genericMethod, list =>
                {
                    bool unresolved;
                    var m = TryInferGenericMethod(method, list, out unresolved);
                    if (unresolved)
                    {
                        throw BindingExceptionManager.InvalidBindingMember(genericMethod.DeclaringType, method.Name);
                    }
                    return m;
                }));
            }
            return(new MethodData(genericMethod));
        }