Public Overrides Function BindToMethod()

in Microsoft.VisualBasic/runtime/msvbalib/Helpers/VBBinder.vb [152:1254]


        Public Overrides Function BindToMethod(ByVal bindingAttr As BindingFlags, ByVal match() As MethodBase, ByRef args() As Object, ByVal modifiers() As ParameterModifier, ByVal culture As CultureInfo, ByVal names() As String, ByRef ObjState As Object) As MethodBase

            Dim HasByRefArgs As Boolean
            Dim ThisMatchHasByRefs As Boolean
            Dim SelectedCount, SelectedIndex As Integer
            Dim SelectedMatch As MethodBase
            Dim ThisMethod As MethodBase
            Dim LastParam As ParameterInfo
            Dim state As VBBinderState
            Dim MethodIndex, NameIndex, ParmIndex, ArgIndex As Integer
            Dim Parameters() As ParameterInfo
            Dim ArgTypes() As Type
            Dim ArgType As Type = Nothing
            Dim ParmType As Type = Nothing
            Dim ParamArrayElementType As Type = Nothing
            Dim ParamArrayIndex As Integer
            Dim LastArgIndexToCheck, LastParmIndexToCheck As Integer
            Dim IsPropertySet As Boolean
            Dim InitialMemberCount As Integer 
            Dim MostSpecific As Integer

            If (match Is Nothing) OrElse (match.Length = 0) Then
                Throw VbMakeException(vbErrors.OLENoPropOrMethod)
            End If

            If (Not m_CachedMember Is Nothing) AndAlso _
               (m_CachedMember.MemberType = MemberTypes.Method) AndAlso _
               (Not match(0) Is Nothing) AndAlso _
               (match(0).Name = m_CachedMember.Name) Then

                Return DirectCast(m_CachedMember, MethodBase)
            End If

            IsPropertySet = ((bindingAttr And BindingFlags.SetProperty) <> 0)

            If Not names Is Nothing AndAlso names.Length = 0 Then
                
                names = Nothing
            End If

            
            
            
            
            
            
            
            
            

            
            
            
            

            SelectedCount = match.Length

            If SelectedCount > 1 Then
                For MethodIndex = 0 To match.GetUpperBound(0)

                    ThisMethod = match(MethodIndex)

                    If ThisMethod Is Nothing Then
                        

                    ElseIf ThisMethod.IsHideBySig Then
                        
                        
                        

                    ElseIf ThisMethod.IsVirtual Then
                        
                        If (ThisMethod.Attributes And MethodAttributes.NewSlot) <> 0 Then
                            
                            
                            
                            Dim j As Integer
                            For j = 0 To match.GetUpperBound(0)

                                If MethodIndex <> j AndAlso (Not match(j) Is Nothing) AndAlso _
                                    ThisMethod.DeclaringType.IsSubclassOf(match(j).DeclaringType) Then
                                    
                                    
                                    match(j) = Nothing
                                    SelectedCount -= 1
                                End If

                            Next j
                        End If

                    Else
                        
                        
                        
                        Dim j As Integer
                        For j = 0 To match.GetUpperBound(0)

                            If MethodIndex <> j AndAlso (Not match(j) Is Nothing) AndAlso _
                                ThisMethod.DeclaringType.IsSubclassOf(match(j).DeclaringType) Then
                                
                                
                                match(j) = Nothing
                                SelectedCount -= 1
                            End If

                        Next j

                    End If

                Next
            End If

            InitialMemberCount = SelectedCount

            
            
            


            
            
            If Not names Is Nothing Then

                For MethodIndex = 0 To match.GetUpperBound(0)

                    ThisMethod = match(MethodIndex)

                    If Not ThisMethod Is Nothing Then

                        Parameters = ThisMethod.GetParameters()

                        
                        LastParmIndexToCheck = Parameters.GetUpperBound(0)
                        If IsPropertySet Then
                            LastParmIndexToCheck -= 1
                        End If

                        If LastParmIndexToCheck >= 0 Then
                            LastParam = Parameters(LastParmIndexToCheck)

                            ParamArrayIndex = PARAMARRAY_NONE

                            If LastParam.ParameterType.IsArray() Then
                                
                                Dim ca() As Object
                                ca = LastParam.GetCustomAttributes(GetType(ParamArrayAttribute), False)
                                If (Not ca Is Nothing) AndAlso (ca.Length > 0) Then
                                    ParamArrayIndex = LastParmIndexToCheck
                                Else
                                    ParamArrayIndex = PARAMARRAY_NONE
                                End If
                            End If
                        End If

                        For NameIndex = 0 To names.GetUpperBound(0)

                            For ParmIndex = 0 To LastParmIndexToCheck

                                If StrComp(names(NameIndex), Parameters(ParmIndex).Name, CompareMethod.Text) = 0 Then
                                    If ParmIndex = ParamArrayIndex AndAlso SelectedCount = 1 Then
                                        Throw VbMakeExceptionEx(vbErrors.NamedArgsNotSupported, GetResourceString(ResID.NamedArgumentOnParamArray))
                                    Else
                                        If ParmIndex = ParamArrayIndex Then
                                            
                                            ParmIndex = LastParmIndexToCheck + 1
                                        Else
                                            
                                        End If
                                        Exit For
                                    End If
                                End If

                            Next ParmIndex

                            
                            
                            If (ParmIndex > LastParmIndexToCheck) Then

                                If SelectedCount = 1 Then
                                    
                                    
                                    
                                    Throw New MissingMemberException(GetResourceString(ResID.Argument_InvalidNamedArg2, names(NameIndex), CalledMethodName()))
                                End If

                                match(MethodIndex) = Nothing
                                SelectedCount -= 1
                                Exit For

                            End If

                        Next NameIndex

                    End If

                Next MethodIndex

            End If

            
            
            
            
            

            
            
            
            
            

            Dim ParamArrayIndexList() As Integer

            
            ParamArrayIndexList = New Integer(match.Length - 1) {}

            For MethodIndex = 0 To match.GetUpperBound(0)

                ThisMethod = match(MethodIndex)

                If Not ThisMethod Is Nothing Then

                    ParamArrayIndex = PARAMARRAY_NONE

                    Parameters = ThisMethod.GetParameters()
                    LastParmIndexToCheck = Parameters.GetUpperBound(0)
                    If IsPropertySet Then
                        LastParmIndexToCheck -= 1
                    End If

                    
                    If LastParmIndexToCheck >= 0 Then

                        LastParam = Parameters(LastParmIndexToCheck)

                        If LastParam.ParameterType.IsArray() Then
                            
                            Dim ca() As Object
                            ca = LastParam.GetCustomAttributes(GetType(ParamArrayAttribute), False)
                            If (Not ca Is Nothing) AndAlso (ca.Length > 0) Then
                                ParamArrayIndex = LastParmIndexToCheck
                            End If
                        End If

                    End If

                    ParamArrayIndexList(MethodIndex) = ParamArrayIndex

                    If (ParamArrayIndex = PARAMARRAY_NONE) AndAlso (args.Length > Parameters.Length) Then
                        
                        If SelectedCount = 1 Then
                            Throw New MissingMemberException(GetResourceString(ResID.NoMethodTakingXArguments2, CalledMethodName(), CStr(GetPropArgCount(args, IsPropertySet))))
                        End If

                        
                        match(MethodIndex) = Nothing
                        SelectedCount -= 1

                    End If

                    Dim LengthOfNonParamArrayArguments As Integer = LastParmIndexToCheck
                    If ParamArrayIndex <> PARAMARRAY_NONE Then
                        LengthOfNonParamArrayArguments -= 1
                    End If

                    If (args.Length < LengthOfNonParamArrayArguments) Then

                        
                        
                        
                        Dim j As Integer
                        For j = args.Length To LengthOfNonParamArrayArguments - 1
                            
                            If (Parameters(j).DefaultValue Is System.DBNull.Value) Then
                                Exit For
                            End If
                        Next j

                        If (j <> LengthOfNonParamArrayArguments) Then
                            
                            If SelectedCount = 1 Then
                                Throw New MissingMemberException(GetResourceString(ResID.NoMethodTakingXArguments2, CalledMethodName(), CStr(GetPropArgCount(args, IsPropertySet))))
                            End If
                            match(MethodIndex) = Nothing
                            SelectedCount -= 1

                        End If

                    End If

                End If

            Next MethodIndex


            
            
            Dim paramOrder As Object() = New Object(match.Length - 1) {}
            Dim ArgIndexes() As Integer

            For MethodIndex = 0 To match.GetUpperBound(0)

                ThisMethod = match(MethodIndex)

                If Not ThisMethod Is Nothing Then

                    Parameters = ThisMethod.GetParameters()

                    If args.Length > Parameters.Length Then
                        ArgIndexes = New Integer(args.Length - 1) {}
                    Else
                        ArgIndexes = New Integer(Parameters.Length - 1) {}
                    End If

                    paramOrder(MethodIndex) = ArgIndexes

                    If (names Is Nothing) Then
                        

                        Dim TmpLastIndex As Integer
                        
                        TmpLastIndex = args.GetUpperBound(0)
                        If IsPropertySet Then
                            TmpLastIndex -= 1
                        End If
                        For ArgIndex = 0 To TmpLastIndex
                            If TypeOf args(ArgIndex) Is System.Reflection.Missing AndAlso (ArgIndex > Parameters.GetUpperBound(0) OrElse Parameters(ArgIndex).IsOptional) Then
                                ArgIndexes(ArgIndex) = ARG_MISSING
                            Else
                                ArgIndexes(ArgIndex) = ArgIndex
                            End If
                        Next ArgIndex


                        TmpLastIndex = ArgIndexes.GetUpperBound(0)
                        
                        For ArgIndex = ArgIndex To TmpLastIndex
                            ArgIndexes(ArgIndex) = ARG_MISSING
                        Next ArgIndex

                        If IsPropertySet Then
                            
                            
                            ArgIndexes(TmpLastIndex) = args.GetUpperBound(0)
                        End If
                    Else
                        
                        
                        
                        

                        Dim ex As Exception

                        ex = CreateParamOrder(IsPropertySet, _
                                            ArgIndexes, _
                                            ThisMethod.GetParameters(), _
                                            args, _
                                            names)
                        If (Not ex Is Nothing) Then
                            If SelectedCount = 1 Then
                                
                                Throw ex
                            Else
                                match(MethodIndex) = Nothing
                                SelectedCount -= 1
                            End If
                        End If
                    End If

                End If

            Next MethodIndex


            

            
            
            
            
            ArgTypes = New Type(args.Length - 1) {}

            For ArgIndex = 0 To args.GetUpperBound(0)
                If Not args(ArgIndex) Is Nothing Then
                    ArgTypes(ArgIndex) = args(ArgIndex).GetType()
                End If
            Next


            
            
            

            For MethodIndex = 0 To match.GetUpperBound(0)

                ThisMethod = match(MethodIndex)

                If Not ThisMethod Is Nothing Then

                    Parameters = ThisMethod.GetParameters()
                    ArgIndexes = CType(paramOrder(MethodIndex), Integer())
                    LastParmIndexToCheck = ArgIndexes.GetUpperBound(0)
                    If IsPropertySet Then
                        LastParmIndexToCheck -= 1
                    End If

                    ParamArrayIndex = ParamArrayIndexList(MethodIndex)
                    If ParamArrayIndex <> PARAMARRAY_NONE Then
                        ParamArrayElementType = Parameters(ParamArrayIndex).ParameterType.GetElementType()
                    Else
                        
                        If ArgIndexes.Length > Parameters.Length Then
                            GoTo ClearMethod7
                        End If
                    End If

                    For ParmIndex = 0 To LastParmIndexToCheck

                        ArgIndex = ArgIndexes(ParmIndex)

                        
                        If (ArgIndex = ARG_MISSING) Then
                            If Parameters(ParmIndex).IsOptional OrElse (ParmIndex = ParamArrayIndexList(MethodIndex)) Then
                                
                                GoTo NextParm7
                            Else
                                If SelectedCount = 1 Then
                                    Throw New MissingMemberException(GetResourceString(ResID.NoMethodTakingXArguments2, CalledMethodName(), CStr(GetPropArgCount(args, IsPropertySet))))
                                End If
                                GoTo ClearMethod7
                            End If
                        End If

                        ArgType = ArgTypes(ArgIndex)
                        
                        
                        
                        If (ArgType Is Nothing) Then
                            
                            GoTo NextParm7
                        End If

                        If (ParamArrayIndex <> PARAMARRAY_NONE) AndAlso (ParmIndex > ParamArrayIndex) Then
                            ParmType = Parameters(ParamArrayIndex).ParameterType.GetElementType()
                        Else
                            ParmType = Parameters(ParmIndex).ParameterType

                            If ParmType.IsByRef Then
                                ParmType = ParmType.GetElementType()
                            End If

                            If (ParmIndex = ParamArrayIndex) Then
                                If (ParmType.IsInstanceOfType(args(ArgIndex)) AndAlso ParmIndex = LastParmIndexToCheck) Then
                                    
                                    GoTo NextParm7
                                End If
                                ParmType = ParamArrayElementType
                            End If

                        End If

                        If ParmType Is ArgType Then
                            GoTo NextParm7
                        End If

                        If (ArgType Is Type.Missing) AndAlso Parameters(ParmIndex).IsOptional Then
                            
                            GoTo NextParm7
                        End If

                        If args(ArgIndex) Is Missing.Value Then
                            GoTo ClearMethod7
                        End If

                        If (ParmType Is GetType(Object)) Then
                            
                            GoTo NextParm7
                        End If

                        If ParmType.IsInstanceOfType(args(ArgIndex)) Then
                            
                            GoTo NextParm7
                        End If

                        
                        Dim ParmTypeCode As TypeCode
                        Dim ArgTypeCode As TypeCode

                        ParmTypeCode = System.Type.GetTypeCode(ParmType)

                        If ArgType Is Nothing Then
                            ArgTypeCode = TypeCode.Empty
                        Else
                            ArgTypeCode = System.Type.GetTypeCode(ArgType)
                        End If

                        Select Case ParmTypeCode

                            Case TypeCode.Boolean, _
                                    TypeCode.Byte, _
                                    TypeCode.Int16, _
                                    TypeCode.Int32, _
                                    TypeCode.Int64, _
                                    TypeCode.Decimal, _
                                    TypeCode.Single, _
                                    TypeCode.Double
                                

                                Select Case ArgTypeCode

                                    Case TypeCode.Boolean, _
                                            TypeCode.Byte, _
                                            TypeCode.Int16, _
                                            TypeCode.Int32, _
                                            TypeCode.Int64, _
                                            TypeCode.Decimal, _
                                            TypeCode.Single, _
                                            TypeCode.Double, _
                                            TypeCode.String
                                        

                                    Case Else
                                        
                                        GoTo ClearMethod7

                                End Select

                            Case TypeCode.Char

                                Select Case ArgTypeCode

                                    Case TypeCode.String
                                        

                                    Case Else
                                        GoTo ClearMethod7

                                End Select

                            Case TypeCode.String
                                Select Case ArgTypeCode
                                    Case TypeCode.Boolean, _
                                            TypeCode.Byte, _
                                            TypeCode.Int16, _
                                            TypeCode.Int32, _
                                            TypeCode.Int64, _
                                            TypeCode.Decimal, _
                                            TypeCode.Double, _
                                            TypeCode.Single, _
                                            TypeCode.Char, _
                                            TypeCode.String, _
                                            TypeCode.Empty
                                        

                                        
                                    Case Else
                                        If ArgType Is GetType(Char()) Then
                                            
                                        Else
                                            GoTo ClearMethod7
                                        End If
                                End Select

                            Case TypeCode.DateTime
                                Select Case ArgTypeCode
                                    Case TypeCode.String
                                        

                                    Case Else
                                        GoTo ClearMethod7
                                End Select

                                
                            Case Else
                                If ParmType Is GetType(Char()) Then
                                    Select Case ArgTypeCode
                                        Case TypeCode.String

                                        Case TypeCode.Object
                                            If Not ArgType Is GetType(Char()) Then
                                                GoTo ClearMethod7
                                            End If

                                        Case Else
                                            GoTo ClearMethod7
                                    End Select

                                Else
                                    
                                    
                                    
                                    
                                    GoTo ClearMethod7
                                End If

                        End Select
NextParm7:
                    Next ParmIndex

                End If
                GoTo NextMethod7
ClearMethod7:
                If SelectedCount = 1 Then
                    
                    If InitialMemberCount = 1 Then
                        ThrowInvalidCast(ArgType, ParmType, ParmIndex)
                    Else
                        Throw New AmbiguousMatchException(GetResourceString(ResID.AmbiguousMatch_NarrowingConversion1, CalledMethodName()))
                    End If
                End If
                match(MethodIndex) = Nothing
                SelectedCount -= 1

NextMethod7:

            Next MethodIndex


            SelectedCount = 0

            
            
            
            For MethodIndex = 0 To match.GetUpperBound(0)

                ThisMethod = match(MethodIndex)

                
                
                If (ThisMethod Is Nothing) Then
                    GoTo NextMethod8
                End If

                ArgIndexes = CType(paramOrder(MethodIndex), Integer())

                
                Parameters = ThisMethod.GetParameters()

                ThisMatchHasByRefs = False

                LastParmIndexToCheck = Parameters.GetUpperBound(0)
                If IsPropertySet Then
                    LastParmIndexToCheck -= 1
                End If

                LastArgIndexToCheck = args.GetUpperBound(0)
                If IsPropertySet Then
                    LastArgIndexToCheck -= 1
                End If
                ParamArrayIndex = ParamArrayIndexList(MethodIndex)
                If ParamArrayIndex <> PARAMARRAY_NONE Then
                    ParamArrayElementType = Parameters(LastParmIndexToCheck).ParameterType.GetElementType()
                End If

                For ParmIndex = 0 To LastParmIndexToCheck

                    If ParmIndex = ParamArrayIndex Then
                        ParmType = ParamArrayElementType
                    Else
                        ParmType = Parameters(ParmIndex).ParameterType
                    End If

                    If ParmType.IsByRef Then
                        ThisMatchHasByRefs = True
                        ParmType = ParmType.GetElementType()
                    End If

                    ArgIndex = ArgIndexes(ParmIndex)

                    If (ArgIndex = ARG_MISSING) AndAlso Parameters(ParmIndex).IsOptional _
                                OrElse (ParmIndex = ParamArrayIndexList(MethodIndex)) Then
                        
                        GoTo NextParm8
                    End If

                    ArgType = ArgTypes(ArgIndex)

                    If (ArgType Is Nothing) Then
                        
                        GoTo NextParm8
                    End If

                    If (ArgType Is Type.Missing) AndAlso Parameters(ParmIndex).IsOptional Then
                        GoTo NextParm8
                    End If

                    If ParmType Is ArgType Then
                        GoTo NextParm8
                    End If

                    If (ParmType Is GetType(Object)) Then
                        GoTo NextParm8
                    End If

                    
                    Dim ParmTypeCode As TypeCode
                    Dim ArgTypeCode As TypeCode

                    ParmTypeCode = System.Type.GetTypeCode(ParmType)

                    If ArgType Is Nothing Then
                        ArgTypeCode = TypeCode.Empty
                    Else
                        ArgTypeCode = System.Type.GetTypeCode(ArgType)
                    End If

                    Select Case ParmTypeCode

                        Case TypeCode.Boolean, _
                                TypeCode.Byte, _
                                TypeCode.Int16, _
                                TypeCode.Int32, _
                                TypeCode.Int64, _
                                TypeCode.Decimal, _
                                TypeCode.Single, _
                                TypeCode.Double
                            

                            Select Case ArgTypeCode

                                Case TypeCode.Boolean, _
                                        TypeCode.Byte, _
                                        TypeCode.Int16, _
                                        TypeCode.Int32, _
                                        TypeCode.Int64, _
                                        TypeCode.Decimal, _
                                        TypeCode.Single, _
                                        TypeCode.Double, _
                                        TypeCode.String
                                    

                                Case Else 
                                    If SelectedCount = 0 Then
                                        ThrowInvalidCast(ArgType, ParmType, ParmIndex)
                                    End If

                            End Select

                        Case TypeCode.Char
                        Case TypeCode.String
                        Case TypeCode.DateTime

                        Case Else

                    End Select

NextParm8:
                Next


                
                
                If (ParmIndex > LastParmIndexToCheck) Then
                    
                    If MethodIndex <> SelectedCount Then
                        match(SelectedCount) = match(MethodIndex)
                        paramOrder(SelectedCount) = paramOrder(MethodIndex)
                        ParamArrayIndexList(SelectedCount) = ParamArrayIndexList(MethodIndex)
                        match(MethodIndex) = Nothing
                    End If
                    SelectedCount += 1
                    If ThisMatchHasByRefs Then
                        HasByRefArgs = True
                    End If
                Else
                    match(MethodIndex) = Nothing
                End If
NextMethod8:
            Next

            If (SelectedCount = 0) Then
                Throw New MissingMemberException(GetResourceString(ResID.NoMethodTakingXArguments2, CalledMethodName(), CStr(GetPropArgCount(args, IsPropertySet))))
            End If

            state = New VBBinderState
            m_state = state

            
            ObjState = state

            state.m_OriginalArgs = args

            If (SelectedCount = 1) Then

                
                SelectedIndex = 0

            Else

                
                Dim AmbiguousCount As Integer
                Dim Score, LowestScore As BindScore

                SelectedIndex = 0
                LowestScore = BindScore.Unknown
                AmbiguousCount = 0

                
                
                
                
                

                For MethodIndex = 0 To SelectedCount - 1 

                    ThisMethod = match(MethodIndex)

                    If ThisMethod Is Nothing Then
                        
                    Else

                        ArgIndexes = CType(paramOrder(MethodIndex), Integer())
                        Score = BindingScore(ThisMethod.GetParameters(), ArgIndexes, ArgTypes, IsPropertySet, ParamArrayIndexList(MethodIndex))

                        If Score < LowestScore Then
                            If MethodIndex <> 0 Then
                                match(0) = match(MethodIndex)
                                paramOrder(0) = paramOrder(MethodIndex)
                                ParamArrayIndexList(0) = ParamArrayIndexList(MethodIndex)
                                match(MethodIndex) = Nothing
                            End If
                            AmbiguousCount = 1
                            LowestScore = Score

                        ElseIf Score = LowestScore Then

                            If Score = BindScore.Exact OrElse Score = BindScore.Widening1 Then

                                MostSpecific = GetMostSpecific(match(0), ThisMethod, ArgIndexes, paramOrder, IsPropertySet, ParamArrayIndexList(0), ParamArrayIndexList(MethodIndex), args)

                                If MostSpecific = -1 Then
                                    If AmbiguousCount <> MethodIndex Then
                                        match(AmbiguousCount) = match(MethodIndex)
                                        paramOrder(AmbiguousCount) = paramOrder(MethodIndex)
                                        ParamArrayIndexList(AmbiguousCount) = ParamArrayIndexList(MethodIndex)
                                        match(MethodIndex) = Nothing
                                    End If
                                    AmbiguousCount += 1

                                ElseIf MostSpecific = 0 Then
                                    
                                    

                                Else 

                                    
                                    
                                    
                                    Dim MoreSpecificThanAllMatches As Boolean = True

                                    For AmbiguousIndex As Integer = 1 To AmbiguousCount - 1
                                        If GetMostSpecific(match(AmbiguousIndex), ThisMethod, ArgIndexes, paramOrder, IsPropertySet, ParamArrayIndexList(AmbiguousIndex), ParamArrayIndexList(MethodIndex), args) <> 1 Then
                                            MoreSpecificThanAllMatches = False
                                            Exit For
                                        End If
                                    Next

                                    If MoreSpecificThanAllMatches Then
                                        AmbiguousCount = 0
                                    End If

                                    If MethodIndex <> AmbiguousCount Then
                                        match(AmbiguousCount) = match(MethodIndex)
                                        paramOrder(AmbiguousCount) = paramOrder(MethodIndex)
                                        ParamArrayIndexList(AmbiguousCount) = ParamArrayIndexList(MethodIndex)
                                        match(MethodIndex) = Nothing
                                    End If
                                    AmbiguousCount += 1
                                End If

                            Else
                                If AmbiguousCount <> MethodIndex Then
                                    match(AmbiguousCount) = match(MethodIndex)
                                    paramOrder(AmbiguousCount) = paramOrder(MethodIndex)
                                    ParamArrayIndexList(AmbiguousCount) = ParamArrayIndexList(MethodIndex)
                                    match(MethodIndex) = Nothing
                                End If
                                AmbiguousCount += 1
                            End If

                        Else
                            
                            match(MethodIndex) = Nothing
                        End If

                    End If

                Next MethodIndex

                If (AmbiguousCount > 1) Then
                    
                    
                    For MethodIndex = 0 To match.GetUpperBound(0)

                        ThisMethod = match(MethodIndex)
                        If Not ThisMethod Is Nothing Then
                            
                            
                            
                            Dim j As Integer
                            For j = 0 To match.GetUpperBound(0)

                                If MethodIndex <> j AndAlso (Not match(j) Is Nothing) AndAlso _
                                    (ThisMethod Is match(j) OrElse _
                                        (ThisMethod.DeclaringType.IsSubclassOf(match(j).DeclaringType) AndAlso _
                                         MethodsDifferOnlyByReturnType(ThisMethod, match(j)))) Then
                                    
                                    
                                    
                                    match(j) = Nothing
                                    AmbiguousCount -= 1
                                End If

                            Next j
                        End If
                    Next
                    Diagnostics.Debug.Assert(AmbiguousCount > 0)
                    
                    For MethodIndex = 0 To match.GetUpperBound(0)
                        If match(MethodIndex) Is Nothing Then
                            Dim j As Integer
                            Dim TmpMatch As MethodBase
                            For j = MethodIndex + 1 To match.GetUpperBound(0)
                                TmpMatch = match(j)
                                If Not TmpMatch Is Nothing Then
                                    match(MethodIndex) = TmpMatch
                                    paramOrder(MethodIndex) = paramOrder(j)
                                    ParamArrayIndexList(MethodIndex) = ParamArrayIndexList(j)
                                    match(j) = Nothing
                                End If
                            Next j
                        End If
                    Next MethodIndex
                End If

                If (AmbiguousCount > 1) Then
                    Dim Msg As String = ControlChars.CrLf & "    " & MethodToString(match(0))
                    For MethodIndex = 1 To AmbiguousCount - 1
                        Msg = Msg & ControlChars.CrLf & "    " & MethodToString(match(MethodIndex))
                    Next MethodIndex

                    Select Case LowestScore
                        Case BindScore.Exact
                            Throw New AmbiguousMatchException(GetResourceString(ResID.AmbiguousCall_ExactMatch2, CalledMethodName(), Msg))

                        Case BindScore.Widening0, BindScore.Widening1
                            Throw New AmbiguousMatchException(GetResourceString(ResID.AmbiguousCall_WideningConversion2, CalledMethodName(), Msg))

                        Case Else
                            
                            
                            Throw New AmbiguousMatchException(GetResourceString(ResID.AmbiguousCall2, CalledMethodName(), Msg))
                    End Select
                End If

            End If

            SelectedMatch = match(SelectedIndex)

            ArgIndexes = CType(paramOrder(SelectedIndex), Integer())

            If (Not names Is Nothing) Then
                ReorderParams(ArgIndexes, args, state)
            End If

            Dim parms() As ParameterInfo = SelectedMatch.GetParameters()

            If args.Length > 0 Then
                state.m_ByRefFlags = New Boolean(args.GetUpperBound(0)) {}

                
                
                HasByRefArgs = False

                For ParmIndex = 0 To parms.GetUpperBound(0)
                    If parms(ParmIndex).ParameterType.IsByRef Then
                        If state.m_OriginalParamOrder Is Nothing Then
                            If ParmIndex < state.m_ByRefFlags.Length Then
                                state.m_ByRefFlags(ParmIndex) = True
                            End If
                        Else
                            If ParmIndex < state.m_OriginalParamOrder.Length Then
                                Dim OriginalParmIndex As Integer = state.m_OriginalParamOrder(ParmIndex)
                                If OriginalParmIndex >= 0 Then
                                    state.m_ByRefFlags(OriginalParmIndex) = True
                                End If
                            End If
                        End If
                        HasByRefArgs = True
                    End If
                Next

                If Not HasByRefArgs Then
                    state.m_ByRefFlags = Nothing
                End If

            Else
                state.m_ByRefFlags = Nothing
            End If

            
            

            ParamArrayIndex = ParamArrayIndexList(SelectedIndex)
            If ParamArrayIndex <> PARAMARRAY_NONE Then

                LastParmIndexToCheck = parms.GetUpperBound(0)
                If IsPropertySet Then
                    LastParmIndexToCheck -= 1
                End If

                LastArgIndexToCheck = args.GetUpperBound(0)
                If IsPropertySet Then
                    LastArgIndexToCheck -= 1
                End If

                
                Dim objs() As Object = New Object(parms.Length - 1) {}

                
                For ParmIndex = 0 To Math.Min(LastArgIndexToCheck, ParamArrayIndex) - 1
                    objs(ParmIndex) = ObjectType.CTypeHelper(args(ParmIndex), parms(ParmIndex).ParameterType)
                Next ParmIndex

                
                If LastArgIndexToCheck < ParamArrayIndex Then
                    For ParmIndex = LastArgIndexToCheck + 1 To ParamArrayIndex - 1
                        objs(ParmIndex) = ObjectType.CTypeHelper(parms(ParmIndex).DefaultValue, parms(ParmIndex).ParameterType)
                    Next ParmIndex
                End If

                
                If IsPropertySet Then
                    Dim SetValueIndex As Integer = objs.GetUpperBound(0)
                    objs(SetValueIndex) = ObjectType.CTypeHelper(args(args.GetUpperBound(0)), parms(SetValueIndex).ParameterType)
                End If

                If LastArgIndexToCheck = -1 Then
                    

                    
                    objs(ParamArrayIndex) = System.Array.CreateInstance(ParamArrayElementType, 0)
                Else
                    ParamArrayElementType = parms(LastParmIndexToCheck).ParameterType.GetElementType()

                    Dim ParamArrayLength As Integer = args.Length - parms.Length + 1

                    ParmType = parms(LastParmIndexToCheck).ParameterType
                    If ParamArrayLength = 1 AndAlso ParmType.IsArray AndAlso (args(ParamArrayIndex) Is Nothing OrElse ParmType.IsInstanceOfType(args(ParamArrayIndex))) Then
                        objs(ParamArrayIndex) = args(ParamArrayIndex)

                    Else

                        If ParamArrayElementType Is GetType(Object) Then
                            
                            Dim ObjArray() As Object = New Object(ParamArrayLength - 1) {}
                            For ArgIndex = 0 To ParamArrayLength - 1
                                ObjArray(ArgIndex) = ObjectType.CTypeHelper(args(ArgIndex + ParamArrayIndex), ParamArrayElementType)
                            Next ArgIndex
                            
                            objs(ParamArrayIndex) = ObjArray
                        Else
                            
                            Dim TypeArray As System.Array = System.Array.CreateInstance(ParamArrayElementType, ParamArrayLength)
                            For ArgIndex = 0 To ParamArrayLength - 1
                                TypeArray.SetValue(ObjectType.CTypeHelper(args(ArgIndex + ParamArrayIndex), ParamArrayElementType), ArgIndex)
                            Next ArgIndex
                            
                            objs(ParamArrayIndex) = TypeArray
                        End If

                    End If

                End If
                args = objs
            Else
                Dim objs() As Object = New Object(parms.Length - 1) {}
                Dim MappedArgIndex As Integer

                For ArgIndex = 0 To objs.GetUpperBound(0)
                    MappedArgIndex = ArgIndexes(ArgIndex)
                    If MappedArgIndex >= 0 AndAlso MappedArgIndex <= args.GetUpperBound(0) Then
                        objs(ArgIndex) = ObjectType.CTypeHelper(args(MappedArgIndex), parms(ArgIndex).ParameterType)
                    Else
                        objs(ArgIndex) = ObjectType.CTypeHelper(parms(ArgIndex).DefaultValue, parms(ArgIndex).ParameterType)
                    End If
                Next ArgIndex

                For ParmIndex = ArgIndex To parms.GetUpperBound(0)
                    objs(ParmIndex) = ObjectType.CTypeHelper(parms(ParmIndex).DefaultValue, parms(ParmIndex).ParameterType)
                Next
                args = objs
            End If

            
            
            Debug.Assert(Not SelectedMatch Is Nothing, "Should have already thrown an exception")
            If SelectedMatch Is Nothing Then
                Throw New MissingMemberException(GetResourceString(ResID.NoMethodTakingXArguments2, CalledMethodName(), CStr(GetPropArgCount(args, IsPropertySet))))
            End If
            Return SelectedMatch

        End Function