Esempio n. 1
0
        [System.Security.SecuritySafeCritical]  // auto-generated
        public override MethodBase SelectMethod(BindingFlags bindingAttr,MethodBase[] match,Type[] types,ParameterModifier[] modifiers)
        {
            int i;
            int j;
            
            Type[] realTypes = new Type[types.Length];
            for (i=0;i<types.Length;i++) {
                realTypes[i] = types[i].UnderlyingSystemType;
                if (!(realTypes[i] is RuntimeType))
                    throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"types");
            }
            types = realTypes;
            
            // We don't automatically jump out on exact match.
            if (match == null || match.Length == 0)
                throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), "match");

            MethodBase[] candidates = (MethodBase[]) match.Clone();
            
            // Find all the methods that can be described by the types parameter. 
            //  Remove all of them that cannot.
            int CurIdx = 0;
            for (i=0;i<candidates.Length;i++) {
                ParameterInfo[] par = candidates[i].GetParametersNoCopy();
                if (par.Length != types.Length)
                    continue;
                for (j=0;j<types.Length;j++) {
                    Type pCls = par[j].ParameterType;
                    if (pCls == types[j])
                        continue;
                    if (pCls == typeof(Object))
                        continue;
                    if (pCls.IsPrimitive) {
                        if (!(types[j].UnderlyingSystemType is RuntimeType) ||
                            !CanConvertPrimitive((RuntimeType)types[j].UnderlyingSystemType,(RuntimeType)pCls.UnderlyingSystemType))
                            break;
                    }
                    else {
                        if (!pCls.IsAssignableFrom(types[j]))
                            break;
                    }
                }
                if (j == types.Length)
                    candidates[CurIdx++] = candidates[i];
            }
            if (CurIdx == 0)
                return null;
            if (CurIdx == 1)
                return candidates[0];
            
            // Walk all of the methods looking the most specific method to invoke
            int currentMin = 0;
            bool ambig = false;
            int[] paramOrder = new int[types.Length];
            for (i=0;i<types.Length;i++)
                paramOrder[i] = i;
            for (i=1;i<CurIdx;i++) {
                int newMin = FindMostSpecificMethod(candidates[currentMin], paramOrder, null, candidates[i], paramOrder, null, types, null);
                if (newMin == 0)
                    ambig = true;
                else {
                    if (newMin == 2) {
                        currentMin = i;
                        ambig = false;
                        currentMin = i;
                    }
                }
            }
            if (ambig)
                throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
            return candidates[currentMin];
        }
Esempio n. 2
0
        // Given a set of methods that match the base criteria, select a method based
        // upon an array of types.  This method should return null if no method matchs
        // the criteria.
        public static MethodBase SelectMethod(MethodBase[] match, Type[] types)
        {
            int i;
            int j;

            MethodBase[] candidates = (MethodBase[])match.Clone();

            // Find all the methods that can be described by the types parameter. 
            //  Remove all of them that cannot.
            int CurIdx = 0;
            for (i = 0; i < candidates.Length; i++)
            {
                ParameterInfo[] par = candidates[i].GetParameters();
                if (par.Length != types.Length)
                    continue;
                for (j = 0; j < types.Length; j++)
                {
                    Type pCls = par[j].ParameterType;
                    if (pCls == types[j])
                    {
                        continue;
                    }
                    if (pCls == typeof(Object))
                    {
                        continue;
                    }
                    if (pCls.GetTypeInfo().IsPrimitive)
                    {
                        if (!CanConvertPrimitive(types[j], pCls))
                        {
                            break;
                        }
                    }
                    else
                    {
                        if (!pCls.GetTypeInfo().IsAssignableFrom(types[j].GetTypeInfo()))
                        {
                            break;
                        }
                    }
                }
                if (j == types.Length)
                {
                    candidates[CurIdx++] = candidates[i];
                }
            }
            if (CurIdx == 0)
            {
                return null;
            }
            if (CurIdx == 1)
            {
                return candidates[0];
            }

            // Walk all of the methods looking the most specific method to invoke
            int currentMin = 0;
            bool ambig = false;
            int[] paramOrder = new int[types.Length];
            for (i = 0; i < types.Length; i++)
            {
                paramOrder[i] = i;
            }
            for (i = 1; i < CurIdx; i++)
            {
                int newMin = FindMostSpecificMethod(candidates[currentMin], paramOrder, null, candidates[i], paramOrder, null, types, null);
                if (newMin == 0)
                {
                    ambig = true;
                }
                else
                {
                    if (newMin == 2)
                    {
                        currentMin = i;
                        ambig = false;
                        currentMin = i;
                    }
                }
            }
            if (ambig)
            {
                throw new AmbiguousMatchException(SR.Arg_AmbiguousMatchException);
            }

            return candidates[currentMin];
        }
Esempio n. 3
0
        [System.Security.SecuritySafeCritical]  // auto-generated
        public override MethodBase BindToMethod(
            BindingFlags bindingAttr, MethodBase[] match, ref Object[] args, 
            ParameterModifier[] modifiers, CultureInfo cultureInfo, String[] names, out Object state)
        {
            if (match == null || match.Length == 0)
                throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), "match");
            Contract.EndContractBlock();

            MethodBase[] candidates = (MethodBase[]) match.Clone();

            int i;
            int j;
        
            state = null;

            #region Map named parameters to candidate parameter postions
            // We are creating an paramOrder array to act as a mapping
            //  between the order of the args and the actual order of the
            //  parameters in the method.  This order may differ because
            //  named parameters (names) may change the order.  If names
            //  is not provided, then we assume the default mapping (0,1,...)
            int[][] paramOrder = new int[candidates.Length][];

            for (i = 0; i < candidates.Length; i++) 
            {
                ParameterInfo[] par = candidates[i].GetParametersNoCopy();

                // args.Length + 1 takes into account the possibility of a last paramArray that can be omitted
                paramOrder[i] = new int[(par.Length > args.Length) ? par.Length : args.Length];

                if (names == null) 
                {
                    // Default mapping
                    for (j = 0; j < args.Length; j++)
                        paramOrder[i][j] = j;
                }
                else 
                {
                    // Named parameters, reorder the mapping.  If CreateParamOrder fails, it means that the method
                    // doesn't have a name that matchs one of the named parameters so we don't consider it any further.
                     if (!CreateParamOrder(paramOrder[i], par, names))
                         candidates[i] = null;
                }               
            }
            #endregion

            Type[] paramArrayTypes = new Type[candidates.Length];
            
            Type[] argTypes = new Type[args.Length];

            #region Cache the type of the provided arguments
            // object that contain a null are treated as if they were typeless (but match either object 
            // references or value classes).  We mark this condition by placing a null in the argTypes array.
            for (i = 0; i < args.Length; i++) 
            {
                if (args[i] != null)
                {
                    argTypes[i] = args[i].GetType();
                }
            }
            #endregion

            
            // Find the method that matches...
            int CurIdx = 0;
            bool defaultValueBinding = ((bindingAttr & BindingFlags.OptionalParamBinding) != 0);

            Type paramArrayType = null;

            #region Filter methods by parameter count and type
            for (i = 0; i < candidates.Length; i++) 
            {
                paramArrayType = null;

                // If we have named parameters then we may have a hole in the candidates array.
                if (candidates[i] == null)
                    continue;
                
                // Validate the parameters.
                ParameterInfo[] par = candidates[i].GetParametersNoCopy();

                #region Match method by parameter count
                if (par.Length == 0) 
                {
                    #region No formal parameters
                    if (args.Length != 0)
                    {
                        if ((candidates[i].CallingConvention & CallingConventions.VarArgs) == 0) 
                            continue;
                    }

                    // This is a valid routine so we move it up the candidates list.
                    paramOrder[CurIdx] = paramOrder[i];
                    candidates[CurIdx++] = candidates[i];

                    continue;
                    #endregion
                }
                else if (par.Length > args.Length) 
                {
                    #region Shortage of provided parameters
                    // If the number of parameters is greater than the number of args then 
                    // we are in the situation were we may be using default values.
                    for (j = args.Length; j < par.Length - 1; j++) 
                    {
                        if (par[j].DefaultValue == System.DBNull.Value)
                           break;
                    }

                    if (j != par.Length - 1)
                        continue;       

                    if (par[j].DefaultValue == System.DBNull.Value) 
                    {
                        if (!par[j].ParameterType.IsArray) 
                            continue;

                        if (!par[j].IsDefined(typeof(ParamArrayAttribute), true)) 
                            continue;

                        paramArrayType = par[j].ParameterType.GetElementType();
                    }
                    #endregion
                }
                else if (par.Length < args.Length) 
                {
                    #region Excess provided parameters
                    // test for the ParamArray case
                    int lastArgPos = par.Length - 1;

                    if (!par[lastArgPos].ParameterType.IsArray) 
                        continue;

                    if (!par[lastArgPos].IsDefined(typeof(ParamArrayAttribute), true)) 
                        continue;

                    if (paramOrder[i][lastArgPos] != lastArgPos)
                        continue; 

                    paramArrayType = par[lastArgPos].ParameterType.GetElementType();
                    #endregion
                }
                else 
                {
                    #region Test for paramArray, save paramArray type
                    int lastArgPos = par.Length - 1;

                    if (par[lastArgPos].ParameterType.IsArray
                        && par[lastArgPos].IsDefined(typeof(ParamArrayAttribute), true)
                        && paramOrder[i][lastArgPos] == lastArgPos)
                    {
                        if (!par[lastArgPos].ParameterType.IsAssignableFrom(argTypes[lastArgPos]))
                            paramArrayType = par[lastArgPos].ParameterType.GetElementType();
                    }
                    #endregion
                }
                #endregion

                Type pCls = null;
                int argsToCheck = (paramArrayType != null) ? par.Length - 1 : args.Length;

                #region Match method by parameter type
                for (j = 0; j < argsToCheck; j++) 
                {
                    #region Classic argument coersion checks
                    // get the formal type
                    pCls = par[j].ParameterType;

                    if (pCls.IsByRef)
                        pCls = pCls.GetElementType();

                    // the type is the same
                    if (pCls == argTypes[paramOrder[i][j]])
                        continue;

                    // a default value is available
                    if (defaultValueBinding && args[paramOrder[i][j]] == Type.Missing)
                        continue;   

                    // the argument was null, so it matches with everything
                    if (args[paramOrder[i][j]] == null)
                        continue;

                    // the type is Object, so it will match everything
                    if (pCls == typeof(Object))
                        continue;

                    // now do a "classic" type check
                    if (pCls.IsPrimitive) 
                    {
                        if (argTypes[paramOrder[i][j]] == null || !CanConvertPrimitiveObjectToType(args[paramOrder[i][j]],(RuntimeType)pCls)) 
                        {
                            break;
                        }
                    }
                    else 
                    {
                        if (argTypes[paramOrder[i][j]] == null)
                            continue;

                        if (!pCls.IsAssignableFrom(argTypes[paramOrder[i][j]])) 
                        {
                            if (argTypes[paramOrder[i][j]].IsCOMObject) 
                            {
                                if (pCls.IsInstanceOfType(args[paramOrder[i][j]]))
                                    continue;
                            }
                            break;
                        }
                    }
                    #endregion
                }

                if (paramArrayType != null && j == par.Length - 1) 
                {
                    #region Check that excess arguments can be placed in the param array
                    for (; j < args.Length; j++) 
                    {
                        if (paramArrayType.IsPrimitive) 
                        {
                            if (argTypes[j] == null || !CanConvertPrimitiveObjectToType(args[j], (RuntimeType)paramArrayType))
                                break;
                        }
                        else 
                        {
                            if (argTypes[j] == null)
                                continue;

                            if (!paramArrayType.IsAssignableFrom(argTypes[j])) 
                            {
                                if (argTypes[j].IsCOMObject) 
                                {
                                    if (paramArrayType.IsInstanceOfType(args[j]))
                                        continue;
                                }

                                break;
                            }
                        }
                    }
                    #endregion
                }
                #endregion

                if (j == args.Length) 
                {
                    #region This is a valid routine so we move it up the candidates list
                    paramOrder[CurIdx] = paramOrder[i];
                    paramArrayTypes[CurIdx] = paramArrayType;
                    candidates[CurIdx++] = candidates[i];
                    #endregion
                }
            }
            #endregion

            // If we didn't find a method 
            if (CurIdx == 0)
                throw new MissingMethodException(Environment.GetResourceString("MissingMember"));

            if (CurIdx == 1) 
            {
                #region Found only one method
                if (names != null) 
                {
                    state = new BinderState((int[])paramOrder[0].Clone(), args.Length, paramArrayTypes[0] != null);
                    ReorderParams(paramOrder[0],args);
                }
                
                // If the parameters and the args are not the same length or there is a paramArray
                //  then we need to create a argument array.
                ParameterInfo[] parms = candidates[0].GetParametersNoCopy();              

                if (parms.Length == args.Length) 
                {
                    if (paramArrayTypes[0] != null) 
                    {
                        Object[] objs = new Object[parms.Length];
                        int lastPos = parms.Length - 1;
                        Array.Copy(args, 0, objs, 0, lastPos);
                        objs[lastPos] = Array.UnsafeCreateInstance(paramArrayTypes[0], 1); 
                        ((Array)objs[lastPos]).SetValue(args[lastPos], 0);
                        args = objs;
                    }
                }
                else if (parms.Length > args.Length) 
                {
                    Object[] objs = new Object[parms.Length];

                    for (i=0;i<args.Length;i++)
                        objs[i] = args[i];

                    for (;i<parms.Length - 1;i++)
                        objs[i] = parms[i].DefaultValue;

                    if (paramArrayTypes[0] != null)
                        objs[i] = Array.UnsafeCreateInstance(paramArrayTypes[0], 0); // create an empty array for the 

                    else
                        objs[i] = parms[i].DefaultValue;

                    args = objs;
                }
                else 
                {
                    if ((candidates[0].CallingConvention & CallingConventions.VarArgs) == 0) 
                    {
                        Object[] objs = new Object[parms.Length];
                        int paramArrayPos = parms.Length - 1;
                        Array.Copy(args, 0, objs, 0, paramArrayPos);
                        objs[paramArrayPos] = Array.UnsafeCreateInstance(paramArrayTypes[0], args.Length - paramArrayPos); 
                        Array.Copy(args, paramArrayPos, (System.Array)objs[paramArrayPos], 0, args.Length - paramArrayPos);
                        args = objs;
                    }
                }
                #endregion

                return candidates[0];
            }
            
            int currentMin = 0;
            bool ambig = false;
            for (i = 1; i < CurIdx; i++) 
            {
                #region Walk all of the methods looking the most specific method to invoke
                int newMin = FindMostSpecificMethod(candidates[currentMin], paramOrder[currentMin], paramArrayTypes[currentMin],
                                                    candidates[i], paramOrder[i], paramArrayTypes[i], argTypes, args);

                if (newMin == 0)
                {
                    ambig = true;
                }
                else  if (newMin == 2) 
                {
                    currentMin = i;
                    ambig = false;
                }
                #endregion
            }

            if (ambig)
                throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));

            // Reorder (if needed)
            if (names != null) {
                state = new BinderState((int[])paramOrder[currentMin].Clone(), args.Length, paramArrayTypes[currentMin] != null);
                ReorderParams(paramOrder[currentMin], args);
            }
                
            // If the parameters and the args are not the same length or there is a paramArray
            //  then we need to create a argument array.
            ParameterInfo[] parameters = candidates[currentMin].GetParametersNoCopy();
            if (parameters.Length == args.Length) 
            {
                if (paramArrayTypes[currentMin] != null) 
                {
                    Object[] objs = new Object[parameters.Length];
                    int lastPos = parameters.Length - 1;
                    Array.Copy(args, 0, objs, 0, lastPos);
                    objs[lastPos] = Array.UnsafeCreateInstance(paramArrayTypes[currentMin], 1); 
                    ((Array)objs[lastPos]).SetValue(args[lastPos], 0);
                    args = objs;
                }
            }
            else if (parameters.Length > args.Length) 
            {
                Object[] objs = new Object[parameters.Length];

                for (i=0;i<args.Length;i++)
                    objs[i] = args[i];

                for (;i<parameters.Length - 1;i++)
                    objs[i] = parameters[i].DefaultValue;

                if (paramArrayTypes[currentMin] != null) 
                {
                    objs[i] = Array.UnsafeCreateInstance(paramArrayTypes[currentMin], 0);
                }
                else
                {
                    objs[i] = parameters[i].DefaultValue;
                }

                args = objs;
            }
            else 
            {
                if ((candidates[currentMin].CallingConvention & CallingConventions.VarArgs) == 0) 
                {
                    Object[] objs = new Object[parameters.Length];
                    int paramArrayPos = parameters.Length - 1;
                    Array.Copy(args, 0, objs, 0, paramArrayPos);
                    objs[paramArrayPos] = Array.UnsafeCreateInstance(paramArrayTypes[currentMin], args.Length - paramArrayPos);
                    Array.Copy(args, paramArrayPos, (System.Array)objs[paramArrayPos], 0, args.Length - paramArrayPos);
                    args = objs;
                }
            }

            return candidates[currentMin];
        }
Esempio n. 4
0
        // This method is passed a set of methods and must choose the best
        // fit.  The methods all have the same number of arguments and the object
        // array args.  On exit, this method will choice the best fit method
        // and coerce the args to match that method.  By match, we mean all primitive
        // arguments are exact matchs and all object arguments are exact or subclasses
        // of the target.  If the target OR is an interface, the object must implement
        // that interface.  There are a couple of exceptions
        // thrown when a method cannot be returned.  If no method matchs the args and
        // ArgumentException is thrown.  If multiple methods match the args then 
        // an AmbiguousMatchException is thrown.
        // 
        // The most specific match will be selected.  
        // 
        public static MethodBase BindToMethod(MethodBase[] match, ref object[] args)
        {
            if (match == null || match.Length == 0)
            {
                throw new ArgumentException(SR.Arg_EmptyArray, "match");
            }

            MethodBase[] candidates = (MethodBase[])match.Clone();

            int i;
            int j;

            #region Map named parameters to candidate parameter postions
            // We are creating an paramOrder array to act as a mapping
            //  between the order of the args and the actual order of the
            //  parameters in the method.  This order may differ because
            //  named parameters (names) may change the order.  If names
            //  is not provided, then we assume the default mapping (0,1,...)
            int[][] paramOrder = new int[candidates.Length][];

            for (i = 0; i < candidates.Length; i++)
            {
                ParameterInfo[] par = candidates[i].GetParameters();

                // args.Length + 1 takes into account the possibility of a last paramArray that can be omitted
                paramOrder[i] = new int[(par.Length > args.Length) ? par.Length : args.Length];

                // Default mapping
                for (j = 0; j < args.Length; j++)
                {
                    paramOrder[i][j] = j;
                }
            }
            #endregion

            Type[] paramArrayTypes = new Type[candidates.Length];

            Type[] argTypes = new Type[args.Length];

            #region Cache the type of the provided arguments
            // object that contain a null are treated as if they were typeless (but match either object 
            // references or value classes).  We mark this condition by placing a null in the argTypes array.
            for (i = 0; i < args.Length; i++)
            {
                if (args[i] != null)
                {
                    argTypes[i] = args[i].GetType();
                }
            }
            #endregion


            // Find the method that matches...
            int CurIdx = 0;

            Type paramArrayType = null;

            #region Filter methods by parameter count and type
            for (i = 0; i < candidates.Length; i++)
            {
                paramArrayType = null;

                // If we have named parameters then we may have a hole in the candidates array.
                if (candidates[i] == null)
                {
                    continue;
                }

                // Validate the parameters.
                ParameterInfo[] par = candidates[i].GetParameters();

                #region Match method by parameter count
                if (par.Length == 0)
                {
                    #region No formal parameters
                    if (args.Length != 0)
                    {
                        if ((candidates[i].CallingConvention & CallingConventions.VarArgs) == 0)
                        {
                            continue;
                        }
                    }

                    // This is a valid routine so we move it up the candidates list.
                    paramOrder[CurIdx] = paramOrder[i];
                    candidates[CurIdx++] = candidates[i];

                    continue;
                    #endregion
                }
                else if (par.Length > args.Length)
                {
                    #region Shortage of provided parameters
                    // If the number of parameters is greater than the number of args then 
                    // we are in the situation were we may be using default values.
                    for (j = args.Length; j < par.Length - 1; j++)
                    {
                        if (!par[j].HasDefaultValue)
                        {
                            break;
                        }
                    }

                    if (j != par.Length - 1)
                    {
                        continue;
                    }

                    if (!par[j].HasDefaultValue)
                    {
                        if (!par[j].ParameterType.IsArray)
                        {
                            continue;
                        }

                        if (!HasParamArrayAttribute(par[j]))
                        {
                            continue;
                        }

                        paramArrayType = par[j].ParameterType.GetElementType();
                    }
                    #endregion
                }
                else if (par.Length < args.Length)
                {
                    #region Excess provided parameters
                    // test for the ParamArray case
                    int lastArgPos = par.Length - 1;

                    if (!par[lastArgPos].ParameterType.IsArray)
                    {
                        continue;
                    }

                    if (!HasParamArrayAttribute(par[lastArgPos]))
                    {
                        continue;
                    }

                    if (paramOrder[i][lastArgPos] != lastArgPos)
                    {
                        continue;
                    }

                    paramArrayType = par[lastArgPos].ParameterType.GetElementType();
                    #endregion
                }
                else
                {
                    #region Test for paramArray, save paramArray type
                    int lastArgPos = par.Length - 1;

                    if (par[lastArgPos].ParameterType.IsArray
                        && HasParamArrayAttribute(par[lastArgPos])
                        && paramOrder[i][lastArgPos] == lastArgPos)
                    {
                        if (!par[lastArgPos].ParameterType.GetTypeInfo().IsAssignableFrom(argTypes[lastArgPos].GetTypeInfo()))
                        {
                            paramArrayType = par[lastArgPos].ParameterType.GetElementType();
                        }
                    }
                    #endregion
                }
                #endregion

                Type pCls = null;
                int argsToCheck = (paramArrayType != null) ? par.Length - 1 : args.Length;

                #region Match method by parameter type
                for (j = 0; j < argsToCheck; j++)
                {
                    #region Classic argument coersion checks
                    // get the formal type
                    pCls = par[j].ParameterType;

                    if (pCls.IsByRef)
                    {
                        pCls = pCls.GetElementType();
                    }

                    // the type is the same
                    if (pCls == argTypes[paramOrder[i][j]])
                    {
                        continue;
                    }

                    // the argument was null, so it matches with everything
                    if (args[paramOrder[i][j]] == null)
                    {
                        continue;
                    }

                    // the type is Object, so it will match everything
                    if (pCls == typeof(Object))
                    {
                        continue;
                    }

                    // now do a "classic" type check
                    if (pCls.GetTypeInfo().IsPrimitive)
                    {
                        if (argTypes[paramOrder[i][j]] == null || !CanConvertPrimitiveObjectToType(args[paramOrder[i][j]], pCls))
                        {
                            break;
                        }
                    }
                    else
                    {
                        if (argTypes[paramOrder[i][j]] == null)
                        {
                            continue;
                        }

                        if (!pCls.GetTypeInfo().IsAssignableFrom(argTypes[paramOrder[i][j]].GetTypeInfo()))
                        {
                            break;
                        }
                    }
                    #endregion
                }

                if (paramArrayType != null && j == par.Length - 1)
                {
                    #region Check that excess arguments can be placed in the param array

                    // Legacy: It's so pathetic that we go to all this trouble let "widening-compatible" params arguments through this screen 
                    // only to end up blowing up with an InvalidCastException anyway because we use Array.Copy() to do the actual copy down below.
                    // Ah, the joys of backward compatibility...
                    for (; j < args.Length; j++)
                    {
                        if (paramArrayType.GetTypeInfo().IsPrimitive)
                        {
                            if (argTypes[j] == null || !CanConvertPrimitiveObjectToType(args[j], paramArrayType))
                            {
                                break;
                            }
                        }
                        else
                        {
                            if (argTypes[j] == null)
                            {
                                continue;
                            }

                            if (!paramArrayType.GetTypeInfo().IsAssignableFrom(argTypes[j].GetTypeInfo()))
                            {
                                break;
                            }
                        }
                    }
                    #endregion
                }
                #endregion

                if (j == args.Length)
                {
                    #region This is a valid routine so we move it up the candidates list
                    paramOrder[CurIdx] = paramOrder[i];
                    paramArrayTypes[CurIdx] = paramArrayType;
                    candidates[CurIdx++] = candidates[i];
                    #endregion
                }
            }
            #endregion

            // If we didn't find a method 
            if (CurIdx == 0)
            {
                throw new MissingMethodException(SR.MissingMember);
            }

            if (CurIdx == 1)
            {
                #region Found only one method
                // If the parameters and the args are not the same length or there is a paramArray
                //  then we need to create a argument array.
                ParameterInfo[] parms = candidates[0].GetParameters();

                if (parms.Length == args.Length)
                {
                    if (paramArrayTypes[0] != null)
                    {
                        Object[] objs = new Object[parms.Length];
                        int lastPos = parms.Length - 1;
                        Array.Copy(args, 0, objs, 0, lastPos);
                        objs[lastPos] = Array.CreateInstance(paramArrayTypes[0], 1);
                        ((Array)objs[lastPos]).SetValue(args[lastPos], 0);
                        args = objs;
                    }
                }
                else if (parms.Length > args.Length)
                {
                    Object[] objs = new Object[parms.Length];

                    for (i = 0; i < args.Length; i++)
                    {
                        objs[i] = args[i];
                    }

                    for (; i < parms.Length - 1; i++)
                    {
                        objs[i] = parms[i].DefaultValue;
                    }

                    if (paramArrayTypes[0] != null)
                    {
                        objs[i] = Array.CreateInstance(paramArrayTypes[0], 0); // create an empty array for the 
                    }

                    else
                    {
                        objs[i] = parms[i].DefaultValue;
                    }

                    args = objs;
                }
                else
                {
                    if ((candidates[0].CallingConvention & CallingConventions.VarArgs) == 0)
                    {
                        Object[] objs = new Object[parms.Length];
                        int paramArrayPos = parms.Length - 1;
                        Array.Copy(args, 0, objs, 0, paramArrayPos);
                        objs[paramArrayPos] = Array.CreateInstance(paramArrayTypes[0], args.Length - paramArrayPos);
                        Array.Copy(args, paramArrayPos, (System.Array)objs[paramArrayPos], 0, args.Length - paramArrayPos);
                        args = objs;
                    }
                }
                #endregion

                return candidates[0];
            }

            int currentMin = 0;
            bool ambig = false;
            for (i = 1; i < CurIdx; i++)
            {
                #region Walk all of the methods looking the most specific method to invoke
                int newMin = FindMostSpecificMethod(candidates[currentMin], paramOrder[currentMin], paramArrayTypes[currentMin],
                                                    candidates[i], paramOrder[i], paramArrayTypes[i], argTypes, args);

                if (newMin == 0)
                {
                    ambig = true;
                }
                else if (newMin == 2)
                {
                    currentMin = i;
                    ambig = false;
                }
                #endregion
            }

            if (ambig)
            {
                throw new AmbiguousMatchException(SR.Arg_AmbiguousMatchException);
            }

            // If the parameters and the args are not the same length or there is a paramArray
            //  then we need to create a argument array.
            ParameterInfo[] parameters = candidates[currentMin].GetParameters();
            if (parameters.Length == args.Length)
            {
                if (paramArrayTypes[currentMin] != null)
                {
                    Object[] objs = new Object[parameters.Length];
                    int lastPos = parameters.Length - 1;
                    Array.Copy(args, 0, objs, 0, lastPos);
                    objs[lastPos] = Array.CreateInstance(paramArrayTypes[currentMin], 1);
                    ((Array)objs[lastPos]).SetValue(args[lastPos], 0);
                    args = objs;
                }
            }
            else if (parameters.Length > args.Length)
            {
                Object[] objs = new Object[parameters.Length];

                for (i = 0; i < args.Length; i++)
                {
                    objs[i] = args[i];
                }

                for (; i < parameters.Length - 1; i++)
                {
                    objs[i] = parameters[i].DefaultValue;
                }

                if (paramArrayTypes[currentMin] != null)
                {
                    objs[i] = Array.CreateInstance(paramArrayTypes[currentMin], 0);
                }
                else
                {
                    objs[i] = parameters[i].DefaultValue;
                }

                args = objs;
            }
            else
            {
                if ((candidates[currentMin].CallingConvention & CallingConventions.VarArgs) == 0)
                {
                    Object[] objs = new Object[parameters.Length];
                    int paramArrayPos = parameters.Length - 1;
                    Array.Copy(args, 0, objs, 0, paramArrayPos);
                    objs[paramArrayPos] = Array.CreateInstance(paramArrayTypes[currentMin], args.Length - paramArrayPos);
                    Array.Copy(args, paramArrayPos, (System.Array)objs[paramArrayPos], 0, args.Length - paramArrayPos);
                    args = objs;
                }
            }

            return candidates[currentMin];
        }
        public override MethodBase BindToMethod(BindingFlags bindingAttr, MethodBase[] match, ref object[] args, ParameterModifier[] modifiers, CultureInfo cultureInfo, string[] names, out object state)
        {
            int num;
            int length;
            if ((match == null) || (match.Length == 0))
            {
                throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), "match");
            }
            MethodBase[] baseArray = (MethodBase[]) match.Clone();
            state = null;
            int[][] numArray = new int[baseArray.Length][];
            for (num = 0; num < baseArray.Length; num++)
            {
                ParameterInfo[] pars = baseArray[num].GetParametersNoCopy();
                numArray[num] = new int[(pars.Length > args.Length) ? pars.Length : args.Length];
                if (names == null)
                {
                    length = 0;
                    while (length < args.Length)
                    {
                        numArray[num][length] = length;
                        length++;
                    }
                }
                else if (!CreateParamOrder(numArray[num], pars, names))
                {
                    baseArray[num] = null;
                }
            }
            Type[] typeArray = new Type[baseArray.Length];
            Type[] types = new Type[args.Length];
            for (num = 0; num < args.Length; num++)
            {
                if (args[num] != null)
                {
                    types[num] = args[num].GetType();
                }
            }
            int index = 0;
            bool flag = (bindingAttr & BindingFlags.OptionalParamBinding) != BindingFlags.Default;
            Type elementType = null;
            for (num = 0; num < baseArray.Length; num++)
            {
                elementType = null;
                if (baseArray[num] != null)
                {
                    ParameterInfo[] infoArray2 = baseArray[num].GetParametersNoCopy();
                    if (infoArray2.Length == 0)
                    {
                        if ((args.Length == 0) || ((baseArray[num].CallingConvention & CallingConventions.VarArgs) != 0))
                        {
                            numArray[index] = numArray[num];
                            baseArray[index++] = baseArray[num];
                        }
                        continue;
                    }
                    if (infoArray2.Length > args.Length)
                    {
                        length = args.Length;
                        while (length < (infoArray2.Length - 1))
                        {
                            if (infoArray2[length].DefaultValue == DBNull.Value)
                            {
                                break;
                            }
                            length++;
                        }
                        if (length != (infoArray2.Length - 1))
                        {
                            continue;
                        }
                        if (infoArray2[length].DefaultValue == DBNull.Value)
                        {
                            if (!infoArray2[length].ParameterType.IsArray || !infoArray2[length].IsDefined(typeof(ParamArrayAttribute), true))
                            {
                                continue;
                            }
                            elementType = infoArray2[length].ParameterType.GetElementType();
                        }
                    }
                    else if (infoArray2.Length < args.Length)
                    {
                        int num4 = infoArray2.Length - 1;
                        if ((!infoArray2[num4].ParameterType.IsArray || !infoArray2[num4].IsDefined(typeof(ParamArrayAttribute), true)) || (numArray[num][num4] != num4))
                        {
                            continue;
                        }
                        elementType = infoArray2[num4].ParameterType.GetElementType();
                    }
                    else
                    {
                        int num5 = infoArray2.Length - 1;
                        if ((infoArray2[num5].ParameterType.IsArray && infoArray2[num5].IsDefined(typeof(ParamArrayAttribute), true)) && ((numArray[num][num5] == num5) && !infoArray2[num5].ParameterType.IsAssignableFrom(types[num5])))
                        {
                            elementType = infoArray2[num5].ParameterType.GetElementType();
                        }
                    }
                    Type parameterType = null;
                    int num6 = (elementType != null) ? (infoArray2.Length - 1) : args.Length;
                    length = 0;
                    while (length < num6)
                    {
                        parameterType = infoArray2[length].ParameterType;
                        if (parameterType.IsByRef)
                        {
                            parameterType = parameterType.GetElementType();
                        }
                        if (((parameterType != types[numArray[num][length]]) && (!flag || (args[numArray[num][length]] != Type.Missing))) && ((args[numArray[num][length]] != null) && (parameterType != typeof(object))))
                        {
                            if (parameterType.IsPrimitive)
                            {
                                if ((types[numArray[num][length]] == null) || !CanConvertPrimitiveObjectToType(args[numArray[num][length]], (RuntimeType) parameterType))
                                {
                                    break;
                                }
                            }
                            else if (((types[numArray[num][length]] != null) && !parameterType.IsAssignableFrom(types[numArray[num][length]])) && (!types[numArray[num][length]].IsCOMObject || !parameterType.IsInstanceOfType(args[numArray[num][length]])))
                            {
                                break;
                            }
                        }
                        length++;
                    }
                    if ((elementType != null) && (length == (infoArray2.Length - 1)))
                    {
                        while (length < args.Length)
                        {
                            if (elementType.IsPrimitive)
                            {
                                if ((types[length] == null) || !CanConvertPrimitiveObjectToType(args[length], (RuntimeType) elementType))
                                {
                                    break;
                                }
                            }
                            else if (((types[length] != null) && !elementType.IsAssignableFrom(types[length])) && (!types[length].IsCOMObject || !elementType.IsInstanceOfType(args[length])))
                            {
                                break;
                            }
                            length++;
                        }
                    }
                    if (length == args.Length)
                    {
                        numArray[index] = numArray[num];
                        typeArray[index] = elementType;
                        baseArray[index++] = baseArray[num];
                    }
                }
            }
            switch (index)
            {
                case 0:
                    throw new MissingMethodException(Environment.GetResourceString("MissingMember"));

                case 1:
                {
                    if (names != null)
                    {
                        state = new BinderState((int[]) numArray[0].Clone(), args.Length, typeArray[0] != null);
                        ReorderParams(numArray[0], args);
                    }
                    ParameterInfo[] infoArray3 = baseArray[0].GetParametersNoCopy();
                    if (infoArray3.Length == args.Length)
                    {
                        if (typeArray[0] != null)
                        {
                            object[] destinationArray = new object[infoArray3.Length];
                            int num7 = infoArray3.Length - 1;
                            Array.Copy(args, 0, destinationArray, 0, num7);
                            destinationArray[num7] = Array.UnsafeCreateInstance(typeArray[0], 1);
                            ((Array) destinationArray[num7]).SetValue(args[num7], 0);
                            args = destinationArray;
                        }
                    }
                    else if (infoArray3.Length > args.Length)
                    {
                        object[] objArray2 = new object[infoArray3.Length];
                        num = 0;
                        while (num < args.Length)
                        {
                            objArray2[num] = args[num];
                            num++;
                        }
                        while (num < (infoArray3.Length - 1))
                        {
                            objArray2[num] = infoArray3[num].DefaultValue;
                            num++;
                        }
                        if (typeArray[0] != null)
                        {
                            objArray2[num] = Array.UnsafeCreateInstance(typeArray[0], 0);
                        }
                        else
                        {
                            objArray2[num] = infoArray3[num].DefaultValue;
                        }
                        args = objArray2;
                    }
                    else if ((baseArray[0].CallingConvention & CallingConventions.VarArgs) == 0)
                    {
                        object[] objArray3 = new object[infoArray3.Length];
                        int num8 = infoArray3.Length - 1;
                        Array.Copy(args, 0, objArray3, 0, num8);
                        objArray3[num8] = Array.UnsafeCreateInstance(typeArray[0], (int) (args.Length - num8));
                        Array.Copy(args, num8, (Array) objArray3[num8], 0, args.Length - num8);
                        args = objArray3;
                    }
                    return baseArray[0];
                }
            }
            int num9 = 0;
            bool flag2 = false;
            for (num = 1; num < index; num++)
            {
                switch (FindMostSpecificMethod(baseArray[num9], numArray[num9], typeArray[num9], baseArray[num], numArray[num], typeArray[num], types, args))
                {
                    case 0:
                        flag2 = true;
                        break;

                    case 2:
                        num9 = num;
                        flag2 = false;
                        break;
                }
            }
            if (flag2)
            {
                throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
            }
            if (names != null)
            {
                state = new BinderState((int[]) numArray[num9].Clone(), args.Length, typeArray[num9] != null);
                ReorderParams(numArray[num9], args);
            }
            ParameterInfo[] parametersNoCopy = baseArray[num9].GetParametersNoCopy();
            if (parametersNoCopy.Length == args.Length)
            {
                if (typeArray[num9] != null)
                {
                    object[] objArray4 = new object[parametersNoCopy.Length];
                    int num11 = parametersNoCopy.Length - 1;
                    Array.Copy(args, 0, objArray4, 0, num11);
                    objArray4[num11] = Array.UnsafeCreateInstance(typeArray[num9], 1);
                    ((Array) objArray4[num11]).SetValue(args[num11], 0);
                    args = objArray4;
                }
            }
            else if (parametersNoCopy.Length > args.Length)
            {
                object[] objArray5 = new object[parametersNoCopy.Length];
                num = 0;
                while (num < args.Length)
                {
                    objArray5[num] = args[num];
                    num++;
                }
                while (num < (parametersNoCopy.Length - 1))
                {
                    objArray5[num] = parametersNoCopy[num].DefaultValue;
                    num++;
                }
                if (typeArray[num9] != null)
                {
                    objArray5[num] = Array.UnsafeCreateInstance(typeArray[num9], 0);
                }
                else
                {
                    objArray5[num] = parametersNoCopy[num].DefaultValue;
                }
                args = objArray5;
            }
            else if ((baseArray[num9].CallingConvention & CallingConventions.VarArgs) == 0)
            {
                object[] objArray6 = new object[parametersNoCopy.Length];
                int num12 = parametersNoCopy.Length - 1;
                Array.Copy(args, 0, objArray6, 0, num12);
                objArray6[num12] = Array.UnsafeCreateInstance(typeArray[num9], (int) (args.Length - num12));
                Array.Copy(args, num12, (Array) objArray6[num12], 0, args.Length - num12);
                args = objArray6;
            }
            return baseArray[num9];
        }
        public override MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers)
        {
            int num;
            Type[] typeArray = new Type[types.Length];
            for (num = 0; num < types.Length; num++)
            {
                typeArray[num] = types[num].UnderlyingSystemType;
                if (!(typeArray[num] is RuntimeType))
                {
                    throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "types");
                }
            }
            types = typeArray;
            if ((match == null) || (match.Length == 0))
            {
                throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), "match");
            }
            MethodBase[] baseArray = (MethodBase[]) match.Clone();
            int num3 = 0;
            for (num = 0; num < baseArray.Length; num++)
            {
                ParameterInfo[] parametersNoCopy = baseArray[num].GetParametersNoCopy();
                if (parametersNoCopy.Length == types.Length)
                {
                    int num2 = 0;
                    while (num2 < types.Length)
                    {
                        Type parameterType = parametersNoCopy[num2].ParameterType;
                        if ((parameterType != types[num2]) && (parameterType != typeof(object)))
                        {
                            if (parameterType.IsPrimitive)
                            {
                                if (!(types[num2].UnderlyingSystemType is RuntimeType) || !CanConvertPrimitive((RuntimeType) types[num2].UnderlyingSystemType, (RuntimeType) parameterType.UnderlyingSystemType))
                                {
                                    break;
                                }
                            }
                            else if (!parameterType.IsAssignableFrom(types[num2]))
                            {
                                break;
                            }
                        }
                        num2++;
                    }
                    if (num2 == types.Length)
                    {
                        baseArray[num3++] = baseArray[num];
                    }
                }
            }
            switch (num3)
            {
                case 0:
                    return null;

                case 1:
                    return baseArray[0];
            }
            int index = 0;
            bool flag = false;
            int[] numArray = new int[types.Length];
            for (num = 0; num < types.Length; num++)
            {
                numArray[num] = num;
            }
            for (num = 1; num < num3; num++)
            {
                switch (FindMostSpecificMethod(baseArray[index], numArray, null, baseArray[num], numArray, null, types, null))
                {
                    case 0:
                        flag = true;
                        break;

                    case 2:
                        index = num;
                        flag = false;
                        index = num;
                        break;
                }
            }
            if (flag)
            {
                throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
            }
            return baseArray[index];
        }
		public override MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers)
		{
			Type[] array = new Type[types.Length];
			for (int i = 0; i < types.Length; i++)
			{
				array[i] = types[i].UnderlyingSystemType;
				if (!(array[i] is RuntimeType))
				{
					throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "types");
				}
			}
			types = array;
			if (match == null || match.Length == 0)
			{
				throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), "match");
			}
			MethodBase[] array2 = (MethodBase[])match.Clone();
			int num = 0;
			for (int i = 0; i < array2.Length; i++)
			{
				ParameterInfo[] parametersNoCopy = array2[i].GetParametersNoCopy();
				if (parametersNoCopy.Length == types.Length)
				{
					int j;
					for (j = 0; j < types.Length; j++)
					{
						Type parameterType = parametersNoCopy[j].ParameterType;
						if (!(parameterType == types[j]) && !(parameterType == typeof(object)))
						{
							if (parameterType.IsPrimitive)
							{
								if (!(types[j].UnderlyingSystemType is RuntimeType))
								{
									break;
								}
								if (!DefaultBinder.CanConvertPrimitive((RuntimeType)types[j].UnderlyingSystemType, (RuntimeType)parameterType.UnderlyingSystemType))
								{
									break;
								}
							}
							else
							{
								if (!parameterType.IsAssignableFrom(types[j]))
								{
									break;
								}
							}
						}
					}
					if (j == types.Length)
					{
						array2[num++] = array2[i];
					}
				}
			}
			if (num == 0)
			{
				return null;
			}
			if (num == 1)
			{
				return array2[0];
			}
			int num2 = 0;
			bool flag = false;
			int[] array3 = new int[types.Length];
			for (int i = 0; i < types.Length; i++)
			{
				array3[i] = i;
			}
			for (int i = 1; i < num; i++)
			{
				int num3 = DefaultBinder.FindMostSpecificMethod(array2[num2], array3, null, array2[i], array3, null, types, null);
				if (num3 == 0)
				{
					flag = true;
				}
				else
				{
					if (num3 == 2)
					{
						num2 = i;
						flag = false;
						num2 = i;
					}
				}
			}
			if (flag)
			{
				throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
			}
			return array2[num2];
		}
		public override MethodBase BindToMethod(BindingFlags bindingAttr, MethodBase[] match, ref object[] args, ParameterModifier[] modifiers, CultureInfo cultureInfo, string[] names, out object state)
		{
			if (match == null || match.Length == 0)
			{
				throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), "match");
			}
			MethodBase[] array = (MethodBase[])match.Clone();
			state = null;
			int[][] array2 = new int[array.Length][];
			for (int i = 0; i < array.Length; i++)
			{
				ParameterInfo[] parametersNoCopy = array[i].GetParametersNoCopy();
				array2[i] = new int[(parametersNoCopy.Length > args.Length) ? parametersNoCopy.Length : args.Length];
				if (names == null)
				{
					for (int j = 0; j < args.Length; j++)
					{
						array2[i][j] = j;
					}
				}
				else
				{
					if (!DefaultBinder.CreateParamOrder(array2[i], parametersNoCopy, names))
					{
						array[i] = null;
					}
				}
			}
			Type[] array3 = new Type[array.Length];
			Type[] array4 = new Type[args.Length];
			for (int i = 0; i < args.Length; i++)
			{
				if (args[i] != null)
				{
					array4[i] = args[i].GetType();
				}
			}
			int num = 0;
			bool flag = (bindingAttr & BindingFlags.OptionalParamBinding) != BindingFlags.Default;
			Type type = null;
			for (int i = 0; i < array.Length; i++)
			{
				type = null;
				if (!(array[i] == null))
				{
					ParameterInfo[] parametersNoCopy2 = array[i].GetParametersNoCopy();
					if (parametersNoCopy2.Length == 0)
					{
						if (args.Length == 0 || (array[i].CallingConvention & CallingConventions.VarArgs) != (CallingConventions)0)
						{
							array2[num] = array2[i];
							array[num++] = array[i];
						}
					}
					else
					{
						int j;
						if (parametersNoCopy2.Length > args.Length)
						{
							j = args.Length;
							while (j < parametersNoCopy2.Length - 1 && parametersNoCopy2[j].DefaultValue != DBNull.Value)
							{
								j++;
							}
							if (j != parametersNoCopy2.Length - 1)
							{
								goto IL_42C;
							}
							if (parametersNoCopy2[j].DefaultValue == DBNull.Value)
							{
								if (!parametersNoCopy2[j].ParameterType.IsArray || !parametersNoCopy2[j].IsDefined(typeof(ParamArrayAttribute), true))
								{
									goto IL_42C;
								}
								type = parametersNoCopy2[j].ParameterType.GetElementType();
							}
						}
						else
						{
							if (parametersNoCopy2.Length < args.Length)
							{
								int num2 = parametersNoCopy2.Length - 1;
								if (!parametersNoCopy2[num2].ParameterType.IsArray || !parametersNoCopy2[num2].IsDefined(typeof(ParamArrayAttribute), true) || array2[i][num2] != num2)
								{
									goto IL_42C;
								}
								type = parametersNoCopy2[num2].ParameterType.GetElementType();
							}
							else
							{
								int num3 = parametersNoCopy2.Length - 1;
								if (parametersNoCopy2[num3].ParameterType.IsArray && parametersNoCopy2[num3].IsDefined(typeof(ParamArrayAttribute), true) && array2[i][num3] == num3 && !parametersNoCopy2[num3].ParameterType.IsAssignableFrom(array4[num3]))
								{
									type = parametersNoCopy2[num3].ParameterType.GetElementType();
								}
							}
						}
						Type type2 = null;
						int num4 = (type != null) ? (parametersNoCopy2.Length - 1) : args.Length;
						for (j = 0; j < num4; j++)
						{
							type2 = parametersNoCopy2[j].ParameterType;
							if (type2.IsByRef)
							{
								type2 = type2.GetElementType();
							}
							if (!(type2 == array4[array2[i][j]]) && (!flag || args[array2[i][j]] != Type.Missing) && args[array2[i][j]] != null && !(type2 == typeof(object)))
							{
								if (type2.IsPrimitive)
								{
									if (array4[array2[i][j]] == null)
									{
										break;
									}
									if (!DefaultBinder.CanConvertPrimitiveObjectToType(args[array2[i][j]], (RuntimeType)type2))
									{
										break;
									}
								}
								else
								{
									if (!(array4[array2[i][j]] == null) && !type2.IsAssignableFrom(array4[array2[i][j]]) && (!array4[array2[i][j]].IsCOMObject || !type2.IsInstanceOfType(args[array2[i][j]])))
									{
										break;
									}
								}
							}
						}
						if (type != null && j == parametersNoCopy2.Length - 1)
						{
							while (j < args.Length)
							{
								if (type.IsPrimitive)
								{
									if (array4[j] == null)
									{
										break;
									}
									if (!DefaultBinder.CanConvertPrimitiveObjectToType(args[j], (RuntimeType)type))
									{
										break;
									}
								}
								else
								{
									if (!(array4[j] == null) && !type.IsAssignableFrom(array4[j]) && (!array4[j].IsCOMObject || !type.IsInstanceOfType(args[j])))
									{
										break;
									}
								}
								j++;
							}
						}
						if (j == args.Length)
						{
							array2[num] = array2[i];
							array3[num] = type;
							array[num++] = array[i];
						}
					}
				}
				IL_42C:;
			}
			if (num == 0)
			{
				throw new MissingMethodException(Environment.GetResourceString("MissingMember"));
			}
			if (num == 1)
			{
				if (names != null)
				{
					state = new DefaultBinder.BinderState((int[])array2[0].Clone(), args.Length, array3[0] != null);
					DefaultBinder.ReorderParams(array2[0], args);
				}
				ParameterInfo[] parametersNoCopy3 = array[0].GetParametersNoCopy();
				if (parametersNoCopy3.Length == args.Length)
				{
					if (array3[0] != null)
					{
						object[] array5 = new object[parametersNoCopy3.Length];
						int num5 = parametersNoCopy3.Length - 1;
						Array.Copy(args, 0, array5, 0, num5);
						array5[num5] = Array.UnsafeCreateInstance(array3[0], 1);
						((Array)array5[num5]).SetValue(args[num5], 0);
						args = array5;
					}
				}
				else
				{
					if (parametersNoCopy3.Length > args.Length)
					{
						object[] array6 = new object[parametersNoCopy3.Length];
						int i;
						for (i = 0; i < args.Length; i++)
						{
							array6[i] = args[i];
						}
						while (i < parametersNoCopy3.Length - 1)
						{
							array6[i] = parametersNoCopy3[i].DefaultValue;
							i++;
						}
						if (array3[0] != null)
						{
							array6[i] = Array.UnsafeCreateInstance(array3[0], 0);
						}
						else
						{
							array6[i] = parametersNoCopy3[i].DefaultValue;
						}
						args = array6;
					}
					else
					{
						if ((array[0].CallingConvention & CallingConventions.VarArgs) == (CallingConventions)0)
						{
							object[] array7 = new object[parametersNoCopy3.Length];
							int num6 = parametersNoCopy3.Length - 1;
							Array.Copy(args, 0, array7, 0, num6);
							array7[num6] = Array.UnsafeCreateInstance(array3[0], args.Length - num6);
							Array.Copy(args, num6, (Array)array7[num6], 0, args.Length - num6);
							args = array7;
						}
					}
				}
				return array[0];
			}
			int num7 = 0;
			bool flag2 = false;
			for (int i = 1; i < num; i++)
			{
				int num8 = DefaultBinder.FindMostSpecificMethod(array[num7], array2[num7], array3[num7], array[i], array2[i], array3[i], array4, args);
				if (num8 == 0)
				{
					flag2 = true;
				}
				else
				{
					if (num8 == 2)
					{
						num7 = i;
						flag2 = false;
					}
				}
			}
			if (flag2)
			{
				throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
			}
			if (names != null)
			{
				state = new DefaultBinder.BinderState((int[])array2[num7].Clone(), args.Length, array3[num7] != null);
				DefaultBinder.ReorderParams(array2[num7], args);
			}
			ParameterInfo[] parametersNoCopy4 = array[num7].GetParametersNoCopy();
			if (parametersNoCopy4.Length == args.Length)
			{
				if (array3[num7] != null)
				{
					object[] array8 = new object[parametersNoCopy4.Length];
					int num9 = parametersNoCopy4.Length - 1;
					Array.Copy(args, 0, array8, 0, num9);
					array8[num9] = Array.UnsafeCreateInstance(array3[num7], 1);
					((Array)array8[num9]).SetValue(args[num9], 0);
					args = array8;
				}
			}
			else
			{
				if (parametersNoCopy4.Length > args.Length)
				{
					object[] array9 = new object[parametersNoCopy4.Length];
					int i;
					for (i = 0; i < args.Length; i++)
					{
						array9[i] = args[i];
					}
					while (i < parametersNoCopy4.Length - 1)
					{
						array9[i] = parametersNoCopy4[i].DefaultValue;
						i++;
					}
					if (array3[num7] != null)
					{
						array9[i] = Array.UnsafeCreateInstance(array3[num7], 0);
					}
					else
					{
						array9[i] = parametersNoCopy4[i].DefaultValue;
					}
					args = array9;
				}
				else
				{
					if ((array[num7].CallingConvention & CallingConventions.VarArgs) == (CallingConventions)0)
					{
						object[] array10 = new object[parametersNoCopy4.Length];
						int num10 = parametersNoCopy4.Length - 1;
						Array.Copy(args, 0, array10, 0, num10);
						array10[num10] = Array.UnsafeCreateInstance(array3[num7], args.Length - num10);
						Array.Copy(args, num10, (Array)array10[num10], 0, args.Length - num10);
						args = array10;
					}
				}
			}
			return array[num7];
		}