[System.Private.CoreLib] Extract RuntimeType for easier refactoring
authorMarek Safar <marek.safar@gmail.com>
Fri, 14 Jun 2019 19:34:05 +0000 (21:34 +0200)
committerMarek Safar <marek.safar@gmail.com>
Sat, 15 Jun 2019 07:28:47 +0000 (09:28 +0200)
Commit migrated from https://github.com/mono/mono/commit/b5b58d67cf6fd4f5431ae2b6c3e3fc4ec71f91b3

src/mono/netcore/System.Private.CoreLib/System.Private.CoreLib.csproj
src/mono/netcore/System.Private.CoreLib/src/System/RuntimeType.cs

index 33f069a..1489629 100644 (file)
       <Compile Include="..\..\mcs\class\corlib\System\TypeSpec.cs" />
 
       <Compile Include="..\..\mcs\class\corlib\System.Runtime.CompilerServices\PreserveDependencyAttribute.cs" />
-      <Compile Include="..\..\mcs\class\referencesource\mscorlib\system\rttype.cs" />
   </ItemGroup>
 
   <Import Project="shared\System.Private.CoreLib.Shared.projitems" />
index f89f2f1..ef3f9d9 100644 (file)
@@ -8,8 +8,8 @@ using System.Threading;
 using System.Collections.Generic;
 using System.Runtime.InteropServices;
 using System.Globalization;
-using System.Security;
-using System.Runtime.Serialization;
+using System.Diagnostics;
+using CustomAttribute=System.MonoCustomAttrs;
 
 namespace System
 {
@@ -24,13 +24,113 @@ namespace System
        }
 
        [StructLayout (LayoutKind.Sequential)]
-       partial class RuntimeType
+       sealed partial class RuntimeType : TypeInfo, ICloneable
        {
+               internal enum MemberListType
+               {
+                       All,
+                       CaseSensitive,
+                       CaseInsensitive,
+                       HandleToInfo
+               }
+
+               // Helper to build lists of MemberInfos. Special cased to avoid allocations for lists of one element.
+               private struct ListBuilder<T> where T : class
+               {
+                       T[] _items;
+                       T _item;
+                       int _count;
+                       int _capacity;
+
+                       public ListBuilder(int capacity)
+                       {
+                               _items = null;
+                               _item = null;
+                               _count = 0;
+                               _capacity = capacity;
+                       }
+
+                       public T this[int index]
+                       {
+                               get
+                               {
+                                       return (_items != null) ? _items[index] : _item;
+                               }
+                       }
+
+                       public T[] ToArray()
+                       {
+                               if (_count == 0)
+                                       return Array.Empty<T> ();
+                               if (_count == 1)
+                                       return new T[1] { _item };
+
+                               Array.Resize(ref _items, _count);
+                               _capacity = _count;
+                               return _items;
+                       }
+
+                       public void CopyTo(Object[] array, int index)
+                       {
+                               if (_count == 0)
+                                       return;
+
+                               if (_count == 1)
+                               {
+                                       array[index] = _item;
+                                       return;
+                               }
+
+                               Array.Copy(_items, 0, array, index, _count);
+                       }
+
+                       public int Count
+                       {
+                               get
+                               {
+                                       return _count;
+                               }
+                       }
+
+                       public void Add(T item)
+                       {
+                               if (_count == 0)
+                               {
+                                       _item = item;
+                               }
+                               else                
+                               {
+                                       if (_count == 1)
+                                       {
+                                               if (_capacity < 2)
+                                                       _capacity = 4;
+                                               _items = new T[_capacity];
+                                               _items[0] = _item;
+                                       }
+                                       else
+                                       if (_capacity == _count)
+                                       {
+                                               int newCapacity = 2 * _capacity;
+                                               Array.Resize(ref _items, newCapacity);
+                                               _capacity = newCapacity;
+                                       }
+
+                                       _items[_count] = item;
+                               }
+                               _count++;
+                       }
+               }        
+
 #region keep in sync with object-internals.h
                [NonSerialized]
                MonoTypeInfo type_info;
 #endregion
 
+               internal static readonly RuntimeType ValueType = (RuntimeType)typeof(System.ValueType);
+
+               private static readonly RuntimeType ObjectType = (RuntimeType)typeof(System.Object);
+               private static readonly RuntimeType StringType = (RuntimeType)typeof(System.String);
+
                internal Object GenericCache;
 
                internal RuntimeType (Object obj)
@@ -95,23 +195,6 @@ namespace System
                        return att.Length != 0 ? ((DefaultMemberAttribute) att [0]).MemberName : null;
                }
 
-               RuntimeConstructorInfo m_serializationCtor;
-               internal RuntimeConstructorInfo GetSerializationCtor()
-               {
-                       if (m_serializationCtor == null) {
-                               var s_SICtorParamTypes = new Type[] { typeof(SerializationInfo), typeof(StreamingContext) };
-
-                               m_serializationCtor = GetConstructor(
-                                       BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
-                                       null,
-                                       CallingConventions.Any,
-                                       s_SICtorParamTypes,
-                                       null) as RuntimeConstructorInfo;
-                       }
-
-                       return m_serializationCtor;
-               }
-
                internal Object CreateInstanceSlow(bool publicOnly, bool wrapExceptions, bool skipCheckThis, bool fillCache)
                {
                        //bool bNeedSecurityCheck = true;
@@ -137,7 +220,7 @@ namespace System
                        if (ctor == null) {
                                Type elementType = this.GetRootElementType();
                                if (ReferenceEquals (elementType, typeof (TypedReference)) || ReferenceEquals (elementType, typeof (RuntimeArgumentHandle)))
-                                       throw new NotSupportedException (Environment.GetResourceString ("NotSupported_ContainsStackPtr"));
+                                       throw new NotSupportedException (("NotSupported_ContainsStackPtr"));
 
                                if (IsValueType)
                                        return CreateInstanceInternal (this);
@@ -153,6 +236,13 @@ namespace System
                        return ctor.InternalInvoke (null, null, wrapExceptions);
                }
 
+               private const BindingFlags MemberBindingMask        = (BindingFlags)0x000000FF;
+               private const BindingFlags InvocationMask           = (BindingFlags)0x0000FF00;
+               private const BindingFlags BinderNonCreateInstance  = BindingFlags.InvokeMethod | BinderGetSetField | BinderGetSetProperty;
+               private const BindingFlags BinderGetSetProperty     = BindingFlags.GetProperty | BindingFlags.SetProperty;
+               private const BindingFlags BinderGetSetField        = BindingFlags.GetField | BindingFlags.SetField;
+               private const BindingFlags BinderNonFieldGetSet     = (BindingFlags)0x00FFF300;
+
                internal Object CheckValue (Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
                {
                        bool failed = false;
@@ -161,12 +251,12 @@ namespace System
                                return res;
 
                        if ((invokeAttr & BindingFlags.ExactBinding) == BindingFlags.ExactBinding)
-                               throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
+                               throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, ("Arg_ObjObjEx"), value.GetType(), this));
 
                        if (binder != null && binder != Type.DefaultBinder)
                                return binder.ChangeType (value, this, culture);
 
-                       throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
+                       throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, ("Arg_ObjObjEx"), value.GetType(), this));
                }
 
                object TryConvertToType (object value, ref bool failed)
@@ -409,6 +499,71 @@ namespace System
                        }
                }
 
+               internal bool IsDelegate()
+               {
+                       return GetBaseType() == typeof(System.MulticastDelegate);
+               }
+
+               public override bool IsAssignableFrom(System.Reflection.TypeInfo? typeInfo)
+               {
+                       if(typeInfo==null) return false;
+                       return IsAssignableFrom(typeInfo.AsType());
+               }
+
+               public override bool IsAssignableFrom(Type? c)
+               {
+                       if ((object)c == null)
+                               return false;
+
+                       if (Object.ReferenceEquals(c, this))
+                               return true;
+
+                       RuntimeType fromType = c.UnderlyingSystemType as RuntimeType;
+
+                       // For runtime type, let the VM decide.
+                       if (fromType != null)
+                       {
+                               // both this and c (or their underlying system types) are runtime types
+                               return RuntimeTypeHandle.CanCastTo(fromType, this);
+                       }
+
+                       // Special case for TypeBuilder to be backward-compatible.
+                       if (RuntimeFeature.IsDynamicCodeSupported && c is System.Reflection.Emit.TypeBuilder)
+                       {
+                               // If c is a subclass of this class, then c can be cast to this type.
+                               if (c.IsSubclassOf(this))
+                                       return true;
+
+                               if (this.IsInterface)
+                               {
+                                       return c.ImplementInterface(this);
+                               }
+                               else if (this.IsGenericParameter)
+                               {
+                                       Type[] constraints = GetGenericParameterConstraints();
+                                       for (int i = 0; i < constraints.Length; i++)
+                                               if (!constraints[i].IsAssignableFrom(c))
+                                                       return false;
+
+                                       return true;
+                               }
+                       }
+
+                       // For anything else we return false.
+                       return false;
+               }               
+
+               protected override bool IsValueTypeImpl()
+               {
+                       // We need to return true for generic parameters with the ValueType constraint.
+                       // So we cannot use the faster RuntimeTypeHandle.IsValueType because it returns 
+                       // false for all generic parameters.
+                       if (this == typeof(ValueType) || this == typeof(Enum)) 
+                               return false;
+
+                       return IsSubclassOf(typeof(ValueType));
+               }
+
                public override bool ContainsGenericParameters {
                        get {
                                if (IsGenericParameter)
@@ -430,7 +585,7 @@ namespace System
                public override Type[] GetGenericParameterConstraints ()
                {
                        if (!IsGenericParameter)
-                               throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
+                               throw new InvalidOperationException(("Arg_NotGenericParameter"));
 
                        var paramInfo = new Mono.RuntimeGenericParamInfoHandle (RuntimeTypeHandle.GetGenericParameterInfo (this));
                        Type[] constraints = paramInfo.Constraints;
@@ -504,7 +659,7 @@ namespace System
                public override InterfaceMapping GetInterfaceMap (Type ifaceType)
                {
                        if (IsGenericParameter)
-                               throw new InvalidOperationException(Environment.GetResourceString("Arg_GenericParameter"));
+                               throw new InvalidOperationException(("Arg_GenericParameter"));
                
                        if ((object)ifaceType == null)
                                throw new ArgumentNullException("ifaceType");
@@ -512,7 +667,7 @@ namespace System
                        RuntimeType ifaceRtType = ifaceType as RuntimeType;
 
                        if (ifaceRtType == null)
-                               throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "ifaceType");
+                               throw new ArgumentException(("Argument_MustBeRuntimeType"), "ifaceType");
 
                        InterfaceMapping res;
                        if (!ifaceType.IsInterface)
@@ -736,41 +891,1964 @@ namespace System
 
                public override bool IsTypeDefinition => RuntimeTypeHandle.IsTypeDefinition (this);
 
-        private const int DEFAULT_PACKING_SIZE = 8;
-
-        internal StructLayoutAttribute GetStructLayoutAttribute ()
-        {
-            if (IsInterface || HasElementType || IsGenericParameter)
-                return null;
-
-            int pack = 0, size = 0;
-            LayoutKind layoutKind = LayoutKind.Auto;
-            switch (Attributes & TypeAttributes.LayoutMask)
-            {
-                case TypeAttributes.ExplicitLayout: layoutKind = LayoutKind.Explicit; break;
-                case TypeAttributes.AutoLayout: layoutKind = LayoutKind.Auto; break;
-                case TypeAttributes.SequentialLayout: layoutKind = LayoutKind.Sequential; break;
-                default: break;
-            }
-
-            CharSet charSet = CharSet.None;
-            switch (Attributes & TypeAttributes.StringFormatMask)
-            {
-                case TypeAttributes.AnsiClass: charSet = CharSet.Ansi; break;
-                case TypeAttributes.AutoClass: charSet = CharSet.Auto; break;
-                case TypeAttributes.UnicodeClass: charSet = CharSet.Unicode; break;
-                default: break;
-            }
-
-            GetPacking (out pack, out size);
-
-            // Metadata parameter checking should not have allowed 0 for packing size.
-            // The runtime later converts a packing size of 0 to 8 so do the same here
-            // because it's more useful from a user perspective. 
-            if (pack == 0)
-                pack = DEFAULT_PACKING_SIZE;
-
-            return new StructLayoutAttribute (layoutKind) { Pack = pack, Size = size, CharSet = charSet };
-        }
-       }
+               private const int DEFAULT_PACKING_SIZE = 8;
+
+               internal StructLayoutAttribute GetStructLayoutAttribute ()
+               {
+                       if (IsInterface || HasElementType || IsGenericParameter)
+                               return null;
+
+                       int pack = 0, size = 0;
+                       LayoutKind layoutKind = LayoutKind.Auto;
+                       switch (Attributes & TypeAttributes.LayoutMask)
+                       {
+                               case TypeAttributes.ExplicitLayout: layoutKind = LayoutKind.Explicit; break;
+                               case TypeAttributes.AutoLayout: layoutKind = LayoutKind.Auto; break;
+                               case TypeAttributes.SequentialLayout: layoutKind = LayoutKind.Sequential; break;
+                               default: break;
+                       }
+
+                       CharSet charSet = CharSet.None;
+                       switch (Attributes & TypeAttributes.StringFormatMask)
+                       {
+                               case TypeAttributes.AnsiClass: charSet = CharSet.Ansi; break;
+                               case TypeAttributes.AutoClass: charSet = CharSet.Auto; break;
+                               case TypeAttributes.UnicodeClass: charSet = CharSet.Unicode; break;
+                               default: break;
+                       }
+
+                       GetPacking (out pack, out size);
+
+                       // Metadata parameter checking should not have allowed 0 for packing size.
+                       // The runtime later converts a packing size of 0 to 8 so do the same here
+                       // because it's more useful from a user perspective. 
+                       if (pack == 0)
+                               pack = DEFAULT_PACKING_SIZE;
+
+                       return new StructLayoutAttribute (layoutKind) { Pack = pack, Size = size, CharSet = charSet };
+               }
+
+               protected override bool IsContextfulImpl() 
+               {
+                       return RuntimeTypeHandle.IsContextful(this);
+               }
+
+               protected override bool IsByRefImpl() 
+               {
+                       return RuntimeTypeHandle.IsByRef(this);
+               }
+
+               protected override bool IsPrimitiveImpl() 
+               {
+                       return RuntimeTypeHandle.IsPrimitive(this);
+               }
+
+               protected override bool IsPointerImpl() 
+               {
+                       return RuntimeTypeHandle.IsPointer(this);
+               }
+
+               protected override bool IsCOMObjectImpl() 
+               {
+                       return RuntimeTypeHandle.IsComObject(this, false);
+               }
+
+               protected override TypeAttributes GetAttributeFlagsImpl() 
+               {
+                       return RuntimeTypeHandle.GetAttributes(this);
+               }
+
+               public override Type BaseType 
+               {
+                       get 
+                       {
+                               return GetBaseType();
+                       }
+               }
+
+               private RuntimeType GetBaseType()
+               {
+                       if (IsInterface)
+                               return null;
+
+                       if (RuntimeTypeHandle.IsGenericVariable(this))
+                       {
+                               Type[] constraints = GetGenericParameterConstraints();
+
+                               RuntimeType baseType = RuntimeType.ObjectType;
+
+                               for (int i = 0; i < constraints.Length; i++)
+                               {
+                                       RuntimeType constraint = (RuntimeType)constraints[i];
+
+                                       if (constraint.IsInterface)
+                                               continue;
+
+                                       if (constraint.IsGenericParameter)
+                                       {
+                                               GenericParameterAttributes special;
+                                               special = constraint.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
+
+                                               if ((special & GenericParameterAttributes.ReferenceTypeConstraint) == 0 &&
+                                                       (special & GenericParameterAttributes.NotNullableValueTypeConstraint) == 0)
+                                                       continue;
+                                       }
+
+                                       baseType = constraint;
+                               }
+
+                               if (baseType == RuntimeType.ObjectType)
+                               {
+                                       GenericParameterAttributes special;
+                                       special = GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
+                                       if ((special & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
+                                               baseType = RuntimeType.ValueType;
+                               }
+
+                               return baseType;
+                       }
+
+                       return RuntimeTypeHandle.GetBaseType(this);
+               }
+
+               public override Type UnderlyingSystemType 
+               {
+                       get 
+                       {
+                               return this;
+                       }
+               }
+
+               protected override bool HasElementTypeImpl() 
+               {
+                       return RuntimeTypeHandle.HasElementType(this);
+               }
+
+               public override GenericParameterAttributes GenericParameterAttributes
+               {
+                       get
+                       {
+                               if (!IsGenericParameter)
+                                       throw new InvalidOperationException(("Arg_NotGenericParameter"));
+
+                               return GetGenericParameterAttributes ();
+                       }
+               }
+
+               public override Module Module
+               {
+                       get
+                       {
+                               return GetRuntimeModule();
+                       }
+               }
+
+               internal RuntimeModule GetRuntimeModule()
+               {
+                       return RuntimeTypeHandle.GetModule(this);
+               }
+
+               public override Assembly Assembly 
+               {
+                       get 
+                       {
+                               return GetRuntimeAssembly();
+                       }
+               }
+
+               internal RuntimeAssembly GetRuntimeAssembly()
+               {
+                       return RuntimeTypeHandle.GetAssembly(this);
+               }
+
+               public override RuntimeTypeHandle TypeHandle 
+               {
+                       get 
+                       {
+                               return new RuntimeTypeHandle(this);
+                       }
+               }
+
+               protected override bool IsArrayImpl() 
+               {
+                       return RuntimeTypeHandle.IsArray(this);
+               }
+
+               public override int GetArrayRank() 
+               {
+                       if (!IsArrayImpl())
+                               throw new ArgumentException(("Argument_HasToBeArrayClass"));
+
+                       return RuntimeTypeHandle.GetArrayRank(this);
+               }
+
+               public override Type GetElementType() 
+               {
+                       return RuntimeTypeHandle.GetElementType(this);
+               }
+
+               public override string[] GetEnumNames()
+               {
+                       if (!IsEnum)
+                               throw new ArgumentException(("Arg_MustBeEnum"), "enumType");
+
+                       String[] ret = Enum.InternalGetNames(this);
+
+                       // Make a copy since we can't hand out the same array since users can modify them
+                       String[] retVal = new String[ret.Length];
+
+                       Array.Copy(ret, retVal, ret.Length);
+
+                       return retVal;
+               }
+
+               public override Array GetEnumValues()
+               {
+                       if (!IsEnum)
+                               throw new ArgumentException(("Arg_MustBeEnum"), "enumType");
+
+                       // Get all of the values
+                       ulong[] values = Enum.InternalGetValues(this);
+
+                       // Create a generic Array
+                       Array ret = Array.CreateInstance(this, values.Length);
+
+                       for (int i = 0; i < values.Length; i++)
+                       {
+                               Object val = Enum.ToObject(this, values[i]);
+                               ret.SetValue(val, i);
+                       }
+
+                       return ret;
+               }
+
+               public override Type GetEnumUnderlyingType()
+               {
+                       if (!IsEnum)
+                               throw new ArgumentException(("Arg_MustBeEnum"), "enumType");
+
+                       return Enum.InternalGetUnderlyingType(this);
+               }
+
+               public override bool IsEnumDefined(object value)
+               {
+                       if (value == null)
+                               throw new ArgumentNullException("value");
+
+                       // Check if both of them are of the same type
+                       RuntimeType valueType = (RuntimeType)value.GetType();
+
+                       // If the value is an Enum then we need to extract the underlying value from it
+                       if (valueType.IsEnum)
+                       {
+                               if (!valueType.IsEquivalentTo(this))
+                                       throw new ArgumentException(SR.Format("Arg_EnumAndObjectMustBeSameType", valueType.ToString(), this.ToString()));
+
+                               valueType = (RuntimeType)valueType.GetEnumUnderlyingType();
+                       }
+
+                       // If a string is passed in
+                       if (valueType == RuntimeType.StringType)
+                       {
+                               // Get all of the Fields, calling GetHashEntry directly to avoid copying
+                               string[] names = Enum.InternalGetNames(this);
+                               if (Array.IndexOf(names, value) >= 0)
+                                       return true;
+                               else
+                                       return false;
+                       }
+
+                       // If an enum or integer value is passed in
+                       if (Type.IsIntegerType(valueType))
+                       {
+                               RuntimeType underlyingType = Enum.InternalGetUnderlyingType(this);
+                               if (underlyingType != valueType)
+                                       throw new ArgumentException(SR.Format("Arg_EnumUnderlyingTypeAndObjectMustBeSameType", valueType.ToString(), underlyingType.ToString()));
+
+                               ulong[] ulValues = Enum.InternalGetValues(this);
+                               ulong ulValue = Enum.ToUInt64(value);
+
+                               return (Array.BinarySearch(ulValues, ulValue) >= 0);
+                       }
+                       else
+                       {
+                               throw new InvalidOperationException(("InvalidOperation_UnknownEnumType"));
+                       }
+               }
+
+               public override string GetEnumName(object value)
+               {
+                       if (value == null)
+                               throw new ArgumentNullException("value");
+
+                       Type valueType = value.GetType();
+
+                       if (!(valueType.IsEnum || IsIntegerType(valueType)))
+                               throw new ArgumentException(("Arg_MustBeEnumBaseTypeOrEnum"), "value");
+
+                       ulong[] ulValues = Enum.InternalGetValues(this);
+                       ulong ulValue = Enum.ToUInt64(value);
+                       int index = Array.BinarySearch(ulValues, ulValue);
+
+                       if (index >= 0)
+                       {
+                               string[] names = Enum.InternalGetNames(this);
+                               return names[index];
+                       }
+
+                       return null;
+               }
+
+               internal RuntimeType[] GetGenericArgumentsInternal()
+               {
+                       return (RuntimeType[]) GetGenericArgumentsInternal (true);
+               }
+
+               public override Type[] GetGenericArguments() 
+               {
+                       Type[] types = GetGenericArgumentsInternal (false);
+
+                       if (types == null)
+                               types = Array.Empty<Type> ();
+
+                       return types;
+               }
+
+               public override Type MakeGenericType(Type[] instantiation)
+               {
+                       if (instantiation == null)
+                               throw new ArgumentNullException("instantiation");
+
+                       RuntimeType[] instantiationRuntimeType = new RuntimeType[instantiation.Length];
+
+                       if (!IsGenericTypeDefinition)
+                               throw new InvalidOperationException(
+                                       SR.Format("Arg_NotGenericTypeDefinition", this));
+
+                       if (GetGenericArguments().Length != instantiation.Length)
+                               throw new ArgumentException(("Argument_GenericArgsCount"), "instantiation");
+
+                       for (int i = 0; i < instantiation.Length; i ++)
+                       {
+                               Type instantiationElem = instantiation[i];
+                               if (instantiationElem == null)
+                                       throw new ArgumentNullException();
+
+                               RuntimeType rtInstantiationElem = instantiationElem as RuntimeType;
+
+                               if (rtInstantiationElem == null)
+                               {
+                                       if (instantiationElem.IsSignatureType)
+                                               return MakeGenericSignatureType (this, instantiation);
+                                       Type[] instantiationCopy = new Type[instantiation.Length];
+                                       for (int iCopy = 0; iCopy < instantiation.Length; iCopy++)
+                                               instantiationCopy[iCopy] = instantiation[iCopy];
+                                       instantiation = instantiationCopy;
+                                       if (!RuntimeFeature.IsDynamicCodeSupported)
+                                               throw new PlatformNotSupportedException();
+                                       return MakeTypeBuilderInstantiation(instantiation);
+                               }
+
+                               instantiationRuntimeType[i] = rtInstantiationElem;
+                       }
+
+                       RuntimeType[] genericParameters = GetGenericArgumentsInternal();
+
+                       SanityCheckGenericArguments(instantiationRuntimeType, genericParameters);
+
+                       Type ret = null;
+                       ret = MakeGenericType (this, instantiationRuntimeType);
+                       if (ret == null)
+                               throw new TypeLoadException ();
+                       return ret;
+               }
+
+               Type MakeTypeBuilderInstantiation(Type[] instantiation)
+               {
+                       return System.Reflection.Emit.TypeBuilderInstantiation.MakeGenericType(this, instantiation);
+               }
+
+               internal static void SanityCheckGenericArguments(RuntimeType[] genericArguments, RuntimeType[] genericParamters)
+               {
+                       if (genericArguments == null)
+                               throw new ArgumentNullException();
+
+                       for(int i = 0; i < genericArguments.Length; i++)
+                       {                
+                               if (genericArguments[i] == null)
+                                       throw new ArgumentNullException();
+                               
+                               ThrowIfTypeNeverValidGenericArgument(genericArguments[i]);
+                       }
+
+                       if (genericArguments.Length != genericParamters.Length)
+                               throw new ArgumentException(
+                                       SR.Format("Argument_NotEnoughGenArguments", genericArguments.Length, genericParamters.Length));
+               }
+
+               private static void ThrowIfTypeNeverValidGenericArgument(RuntimeType type)
+               {
+                       if (type.IsPointer || type.IsByRef || type == typeof(void))
+                               throw new ArgumentException(
+                                       SR.Format("Argument_NeverValidGenericArgument", type.ToString()));
+               }
+
+               private static void SplitName(string fullname, out string name, out string ns)
+               {
+                       name = null;
+                       ns = null;
+
+                       if (fullname == null)
+                               return;
+
+                       // Get namespace
+                       int nsDelimiter = fullname.LastIndexOf(".", StringComparison.Ordinal);
+                       if (nsDelimiter != -1 )     
+                       {
+                               ns = fullname.Substring(0, nsDelimiter);
+                               int nameLength = fullname.Length - ns.Length - 1;
+                               if (nameLength != 0)
+                                       name = fullname.Substring(nsDelimiter + 1, nameLength);
+                               else
+                                       name = "";
+                       }
+                       else
+                       {
+                               name = fullname;
+                       }
+               }
+
+               public override bool IsGenericTypeDefinition
+               {
+                       get { return RuntimeTypeHandle.IsGenericTypeDefinition(this); }
+               }
+
+               public override bool IsGenericParameter
+               {
+                       get { return RuntimeTypeHandle.IsGenericVariable(this); }
+               }
+
+               public override int GenericParameterPosition
+               {
+                       get 
+                       {
+                               if (!IsGenericParameter)
+                                       throw new InvalidOperationException(("Arg_NotGenericParameter"));
+
+                               return GetGenericParameterPosition ();
+                       }
+               }
+
+               public override Type GetGenericTypeDefinition() 
+               {
+                       if (!IsGenericType)
+                               throw new InvalidOperationException(("InvalidOperation_NotGenericType"));
+
+                       return RuntimeTypeHandle.GetGenericTypeDefinition(this);
+               }
+
+               public override bool IsGenericType
+               {
+                       get { return RuntimeTypeHandle.HasInstantiation(this); }
+               }
+
+               public override bool IsConstructedGenericType
+               {
+                       get { return IsGenericType && !IsGenericTypeDefinition; }
+               }
+
+               public Object Clone() 
+               {
+                       return this;
+               }
+
+               public override Object[] GetCustomAttributes(bool inherit)
+               {
+                       return CustomAttribute.GetCustomAttributes(this, inherit);
+               }
+
+               public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
+               {
+                       if ((object)attributeType == null)
+                               throw new ArgumentNullException("attributeType");
+
+                       RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+                       if (attributeRuntimeType == null) 
+                               throw new ArgumentException(("Arg_MustBeType"),"attributeType");
+
+                       return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit);
+               }
+
+               public override bool IsDefined(Type attributeType, bool inherit)
+               {
+                       if ((object)attributeType == null)
+                               throw new ArgumentNullException("attributeType");
+
+                       RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+                       if (attributeRuntimeType == null) 
+                               throw new ArgumentException(("Arg_MustBeType"),"attributeType");
+
+                       return CustomAttribute.IsDefined(this, attributeRuntimeType, inherit);
+               }
+
+               public override IList<CustomAttributeData> GetCustomAttributesData()
+               {
+                       return CustomAttributeData.GetCustomAttributesInternal(this);
+               }
+
+               public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
+               {
+                       return GetMethodCandidates(null, bindingAttr, CallingConventions.Any, null, -1, false).ToArray();
+               }
+
+               public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
+               {
+                       return GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, null, false).ToArray();
+               }
+
+               public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
+               {
+                       return GetPropertyCandidates(null, bindingAttr, null, false).ToArray();
+               }
+
+               public override EventInfo[] GetEvents(BindingFlags bindingAttr)
+               {
+                       return GetEventCandidates(null, bindingAttr, false).ToArray();
+               }
+
+               public override FieldInfo[] GetFields(BindingFlags bindingAttr)
+               {
+                       return GetFieldCandidates(null, bindingAttr, false).ToArray();
+               }
+
+               public override Type[] GetNestedTypes(BindingFlags bindingAttr)
+               {
+                       return GetNestedTypeCandidates(null, bindingAttr, false).ToArray();
+               }
+
+               public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
+               {
+                       ListBuilder<MethodInfo> methods = GetMethodCandidates(null, bindingAttr, CallingConventions.Any, null, -1, false);
+                       ListBuilder<ConstructorInfo> constructors = GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, null, false);
+                       ListBuilder<PropertyInfo> properties = GetPropertyCandidates(null, bindingAttr, null, false);
+                       ListBuilder<EventInfo> events = GetEventCandidates(null, bindingAttr, false);
+                       ListBuilder<FieldInfo> fields = GetFieldCandidates(null, bindingAttr, false);
+                       ListBuilder<Type> nestedTypes = GetNestedTypeCandidates(null, bindingAttr, false);
+                       // Interfaces are excluded from the result of GetMembers
+
+                       MemberInfo[] members = new MemberInfo[
+                               methods.Count +
+                               constructors.Count +
+                               properties.Count +
+                               events.Count +
+                               fields.Count +
+                               nestedTypes.Count];
+
+                       int i = 0;
+                       methods.CopyTo(members, i); i += methods.Count;
+                       constructors.CopyTo(members, i); i += constructors.Count;
+                       properties.CopyTo(members, i); i += properties.Count;
+                       events.CopyTo(members, i); i += events.Count;
+                       fields.CopyTo(members, i); i += fields.Count;
+                       nestedTypes.CopyTo(members, i); i += nestedTypes.Count;
+
+                       return members;
+               }
+
+               protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers)
+               {
+                       return GetMethodImpl (name, -1, bindingAttr, binder, callConvention, types, modifiers);
+               }
+
+               protected override MethodInfo GetMethodImpl(String name, int genericParamCount,
+                       BindingFlags bindingAttr, Binder? binder, CallingConventions callConv, 
+                       Type[]? types, ParameterModifier[]? modifiers) 
+               {
+                       ListBuilder<MethodInfo> candidates = GetMethodCandidates(name, bindingAttr, callConv, types, genericParamCount, false);
+                       if (candidates.Count == 0) 
+                               return null;
+
+                       if (types == null || types.Length == 0) 
+                       {
+                               MethodInfo firstCandidate = candidates[0];
+
+                               if (candidates.Count == 1)
+                               {
+                                       return firstCandidate;
+                               }
+                               else if (types == null) 
+                               { 
+                                       for (int j = 1; j < candidates.Count; j++)
+                                       {
+                                               MethodInfo methodInfo = candidates[j];
+                                               if (!System.DefaultBinder.CompareMethodSig (methodInfo, firstCandidate))
+                                                       throw new AmbiguousMatchException(("Arg_AmbiguousMatchException"));
+                                       }
+
+                                       // All the methods have the exact same name and sig so return the most derived one.
+                                       return System.DefaultBinder.FindMostDerivedNewSlotMeth(candidates.ToArray(), candidates.Count) as MethodInfo;
+                               }
+                       }   
+
+                       if (binder == null) 
+                               binder = DefaultBinder;
+
+                       return binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as MethodInfo;                  
+               }
+
+               protected override ConstructorInfo GetConstructorImpl(
+                       BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, 
+                       Type[] types, ParameterModifier[]? modifiers)
+               {
+                       ListBuilder<ConstructorInfo> candidates = GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, types, false);
+
+                       if (candidates.Count == 0)
+                               return null;
+                       
+                       if (types.Length == 0 && candidates.Count == 1) 
+                       {
+                               ConstructorInfo firstCandidate = candidates[0];
+
+                               ParameterInfo[] parameters = firstCandidate.GetParametersNoCopy();
+                               if (parameters == null || parameters.Length == 0) 
+                               {
+                                       return firstCandidate;
+                               }
+                       }
+
+                       if ((bindingAttr & BindingFlags.ExactBinding) != 0)
+                               return System.DefaultBinder.ExactBinding(candidates.ToArray(), types, modifiers) as ConstructorInfo;
+
+                       if (binder == null)
+                               binder = DefaultBinder;
+
+                       return binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as ConstructorInfo;
+               }
+
+
+               protected override PropertyInfo GetPropertyImpl(
+                       String name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) 
+               {
+                       if (name == null) throw new ArgumentNullException();
+
+                       ListBuilder<PropertyInfo> candidates = GetPropertyCandidates(name, bindingAttr, types, false);
+
+                       if (candidates.Count == 0)
+                               return null;
+                       
+                       if (types == null || types.Length == 0) 
+                       {
+                               // no arguments
+                               if (candidates.Count == 1) 
+                               {
+                                       PropertyInfo firstCandidate = candidates[0];
+
+                                       if ((object)returnType != null && !returnType.IsEquivalentTo(firstCandidate.PropertyType))
+                                               return null;
+
+                                       return firstCandidate;
+                               }
+                               else 
+                               {
+                                       if ((object)returnType == null)
+                                               // if we are here we have no args or property type to select over and we have more than one property with that name
+                                               throw new AmbiguousMatchException(("Arg_AmbiguousMatchException"));
+                               }
+                       }
+                       
+                       if ((bindingAttr & BindingFlags.ExactBinding) != 0)
+                               return System.DefaultBinder.ExactPropertyBinding(candidates.ToArray(), returnType, types, modifiers);
+
+                       if (binder == null)
+                               binder = DefaultBinder;
+                       
+                       return binder.SelectProperty(bindingAttr, candidates.ToArray(), returnType, types, modifiers);
+               }
+
+               public override EventInfo GetEvent(String name, BindingFlags bindingAttr) 
+               {
+                       if (name == null) throw new ArgumentNullException();
+
+                       bool ignoreCase;
+                       MemberListType listType;
+                       RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
+
+                       RuntimeEventInfo[] cache = GetEvents_internal (name, bindingAttr, listType, this);
+                       EventInfo match = null;
+
+                       bindingAttr ^= BindingFlags.DeclaredOnly;
+
+                       for (int i = 0; i < cache.Length; i++)
+                       {
+                               RuntimeEventInfo eventInfo = cache[i];
+                               if ((bindingAttr & eventInfo.BindingFlags) == eventInfo.BindingFlags)
+                               {
+                                       if (match != null)
+                                               throw new AmbiguousMatchException(("Arg_AmbiguousMatchException"));
+
+                                       match = eventInfo;
+                               }
+                       }
+
+                       return match;
+               }
+
+               public override FieldInfo GetField(String name, BindingFlags bindingAttr) 
+               {
+                       if (name == null) throw new ArgumentNullException();
+
+                       bool ignoreCase;
+                       MemberListType listType;
+                       RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
+
+                       RuntimeFieldInfo[] cache = GetFields_internal (name, bindingAttr, listType, this);
+                       FieldInfo match = null;
+
+                       bindingAttr ^= BindingFlags.DeclaredOnly;
+                       bool multipleStaticFieldMatches = false;
+
+                       for (int i = 0; i < cache.Length; i++)
+                       {
+                               RuntimeFieldInfo fieldInfo = cache[i];
+                               if ((bindingAttr & fieldInfo.BindingFlags) == fieldInfo.BindingFlags)
+                               {
+                                       if (match != null)
+                                       {
+                                               if (Object.ReferenceEquals(fieldInfo.DeclaringType, match.DeclaringType))
+                                                       throw new AmbiguousMatchException(("Arg_AmbiguousMatchException"));
+
+                                               if ((match.DeclaringType.IsInterface == true) && (fieldInfo.DeclaringType.IsInterface == true))
+                                                       multipleStaticFieldMatches = true;
+                                       }
+                               
+                                       if (match == null || fieldInfo.DeclaringType.IsSubclassOf(match.DeclaringType) || match.DeclaringType.IsInterface)
+                                               match = fieldInfo;
+                               }
+                       }
+
+                       if (multipleStaticFieldMatches && match.DeclaringType.IsInterface)
+                               throw new AmbiguousMatchException(("Arg_AmbiguousMatchException"));
+
+                       return match;
+               }
+
+               public override Type GetInterface(String fullname, bool ignoreCase) 
+               {
+                       if (fullname == null) throw new ArgumentNullException();
+
+                       BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.NonPublic;
+                       
+                       bindingAttr &= ~BindingFlags.Static;
+
+                       if (ignoreCase)
+                               bindingAttr |= BindingFlags.IgnoreCase;
+
+                       string name, ns;
+                       MemberListType listType;
+                       SplitName(fullname, out name, out ns);            
+                       RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
+
+                       List<RuntimeType> list = null;
+                       var nameComparison = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
+                       foreach (RuntimeType t in GetInterfaces ()) {
+
+                               if (!String.Equals(t.Name, name, nameComparison)) {
+                                          continue;
+                               }
+
+                               if (list == null)
+                                       list = new List<RuntimeType> (2);
+
+                               list.Add (t);
+                       }
+
+                       if (list == null)
+                               return null;
+
+                       var cache = list.ToArray ();
+                       RuntimeType match = null;
+
+                       for (int i = 0; i < cache.Length; i++)
+                       {
+                               RuntimeType iface = cache[i];
+                               if (RuntimeType.FilterApplyType(iface, bindingAttr, name, false, ns))
+                               {
+                                       if (match != null)
+                                               throw new AmbiguousMatchException(("Arg_AmbiguousMatchException"));
+
+                                       match = iface;
+                               }
+                       }
+
+                       return match;
+               }
+
+               public override Type GetNestedType(String fullname, BindingFlags bindingAttr) 
+               {
+                       if (fullname == null) throw new ArgumentNullException();
+
+                       bool ignoreCase;
+                       bindingAttr &= ~BindingFlags.Static;
+                       string name, ns;
+                       MemberListType listType;
+                       SplitName(fullname, out name, out ns);            
+                       RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
+                       RuntimeType[] cache = GetNestedTypes_internal (name, bindingAttr, listType);
+                       RuntimeType match = null;
+
+                       for (int i = 0; i < cache.Length; i++)
+                       {
+                               RuntimeType nestedType = cache[i];
+                               if (RuntimeType.FilterApplyType(nestedType, bindingAttr, name, false, ns))
+                               {
+                                       if (match != null)
+                                               throw new AmbiguousMatchException(("Arg_AmbiguousMatchException"));
+
+                                       match = nestedType;
+                               }
+                       }
+
+                       return match;
+               }
+
+               public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr) 
+               {
+                       if (name == null) throw new ArgumentNullException();
+
+                       ListBuilder<MethodInfo> methods = new ListBuilder<MethodInfo>();
+                       ListBuilder<ConstructorInfo> constructors = new ListBuilder<ConstructorInfo>();
+                       ListBuilder<PropertyInfo> properties = new ListBuilder<PropertyInfo>();
+                       ListBuilder<EventInfo> events = new ListBuilder<EventInfo>();
+                       ListBuilder<FieldInfo> fields = new ListBuilder<FieldInfo>(); 
+                       ListBuilder<Type> nestedTypes = new ListBuilder<Type>();
+
+                       int totalCount = 0;
+
+                       // Methods
+                       if ((type & MemberTypes.Method) != 0)
+                       {
+                               methods = GetMethodCandidates(name, bindingAttr, CallingConventions.Any, null, -1, true);
+                               if (type == MemberTypes.Method)
+                                       return methods.ToArray();
+                               totalCount += methods.Count;
+                       }
+
+                       // Constructors
+                       if ((type & MemberTypes.Constructor) != 0)
+                       {
+                               constructors = GetConstructorCandidates(name, bindingAttr, CallingConventions.Any, null, true);
+                               if (type == MemberTypes.Constructor)
+                                       return constructors.ToArray();
+                               totalCount += constructors.Count;
+                       }
+
+                       // Properties
+                       if ((type & MemberTypes.Property) != 0)
+                       {
+                               properties = GetPropertyCandidates(name, bindingAttr, null, true);
+                               if (type == MemberTypes.Property)
+                                       return properties.ToArray();
+                               totalCount += properties.Count;
+                       }
+
+                       // Events
+                       if ((type & MemberTypes.Event) != 0)
+                       {
+                               events = GetEventCandidates(name, bindingAttr, true);
+                               if (type == MemberTypes.Event)
+                                       return events.ToArray();
+                               totalCount += events.Count;
+                       }
+
+                       // Fields
+                       if ((type & MemberTypes.Field) != 0)
+                       {
+                               fields = GetFieldCandidates(name, bindingAttr, true);
+                               if (type == MemberTypes.Field)
+                                       return fields.ToArray();
+                               totalCount += fields.Count;
+                       }
+
+                       // NestedTypes
+                       if ((type & (MemberTypes.NestedType | MemberTypes.TypeInfo)) != 0)
+                       {
+                               nestedTypes = GetNestedTypeCandidates(name, bindingAttr, true);
+                               if (type == MemberTypes.NestedType || type == MemberTypes.TypeInfo)
+                                       return nestedTypes.ToArray();
+                               totalCount += nestedTypes.Count;
+                       }
+
+                       MemberInfo[] compressMembers = (type == (MemberTypes.Method | MemberTypes.Constructor)) ?
+                               new MethodBase[totalCount] : new MemberInfo[totalCount];
+
+                       int i = 0;
+                       methods.CopyTo(compressMembers, i); i += methods.Count;
+                       constructors.CopyTo(compressMembers, i); i += constructors.Count;
+                       properties.CopyTo(compressMembers, i); i += properties.Count;
+                       events.CopyTo(compressMembers, i); i += events.Count;
+                       fields.CopyTo(compressMembers, i); i += fields.Count;
+                       nestedTypes.CopyTo(compressMembers, i); i += nestedTypes.Count;
+
+                       return compressMembers;
+               }
+
+               [DebuggerStepThroughAttribute]
+               [Diagnostics.DebuggerHidden]
+               public override Object InvokeMember(
+                       String name, BindingFlags bindingFlags, Binder? binder, Object? target, 
+                       Object?[]? providedArgs, ParameterModifier[]? modifiers, CultureInfo? culture, String[]? namedParams) 
+               {
+                       if (IsGenericParameter)
+                               throw new InvalidOperationException(("Arg_GenericParameter"));
+               
+                       #region Preconditions
+                       if ((bindingFlags & InvocationMask) == 0)
+                               // "Must specify binding flags describing the invoke operation required."
+                               throw new ArgumentException(("Arg_NoAccessSpec"),"bindingFlags");
+
+                       // Provide a default binding mask if none is provided 
+                       if ((bindingFlags & MemberBindingMask) == 0) 
+                       {
+                               bindingFlags |= BindingFlags.Instance | BindingFlags.Public;
+
+                               if ((bindingFlags & BindingFlags.CreateInstance) == 0) 
+                                       bindingFlags |= BindingFlags.Static;
+                       }
+
+                       // There must not be more named parameters than provided arguments
+                       if (namedParams != null)
+                       {
+                               if (providedArgs != null)
+                               {
+                                       if (namedParams.Length > providedArgs.Length)
+                                               // "Named parameter array can not be bigger than argument array."
+                                               throw new ArgumentException(("Arg_NamedParamTooBig"), "namedParams");
+                               }
+                               else
+                               {
+                                       if (namedParams.Length != 0)
+                                               // "Named parameter array can not be bigger than argument array."
+                                               throw new ArgumentException(("Arg_NamedParamTooBig"), "namedParams");
+                               }
+                       }
+                       #endregion
+                               
+                       #region Check that any named paramters are not null
+                       if (namedParams != null && Array.IndexOf(namedParams, null) != -1)
+                               // "Named parameter value must not be null."
+                               throw new ArgumentException(("Arg_NamedParamNull"),"namedParams");
+                       #endregion
+
+                       int argCnt = (providedArgs != null) ? providedArgs.Length : 0;
+                       
+                       #region Get a Binder
+                       if (binder == null)
+                               binder = DefaultBinder;
+
+                       #endregion
+                       
+                       #region Delegate to Activator.CreateInstance
+                       if ((bindingFlags & BindingFlags.CreateInstance) != 0) 
+                       {
+                               if ((bindingFlags & BindingFlags.CreateInstance) != 0 && (bindingFlags & BinderNonCreateInstance) != 0)
+                                       // "Can not specify both CreateInstance and another access type."
+                                       throw new ArgumentException(("Arg_CreatInstAccess"),"bindingFlags");
+
+                               return Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture);
+                       }
+                       #endregion
+
+                       // PutDispProperty and\or PutRefDispProperty ==> SetProperty.
+                       if ((bindingFlags & (BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty)) != 0)
+                               bindingFlags |= BindingFlags.SetProperty;
+
+                       #region Name
+                       if (name == null)
+                               throw new ArgumentNullException("name");
+                               
+                       if (name.Length == 0 || name.Equals(@"[DISPID=0]")) 
+                       {
+                               name = GetDefaultMemberName();
+
+                               if (name == null) 
+                               {
+                                       // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString
+                                       name = "ToString";
+                               }
+                       }
+                       #endregion
+
+                       #region GetField or SetField
+                       bool IsGetField = (bindingFlags & BindingFlags.GetField) != 0;
+                       bool IsSetField = (bindingFlags & BindingFlags.SetField) != 0;
+
+                       if (IsGetField || IsSetField)
+                       {
+                               #region Preconditions
+                               if (IsGetField)
+                               {
+                                       if (IsSetField)
+                                               // "Can not specify both Get and Set on a field."
+                                               throw new ArgumentException(("Arg_FldSetGet"),"bindingFlags");
+
+                                       if ((bindingFlags & BindingFlags.SetProperty) != 0)
+                                               // "Can not specify both GetField and SetProperty."
+                                               throw new ArgumentException(("Arg_FldGetPropSet"),"bindingFlags");
+                               }
+                               else
+                               {
+                                       if (providedArgs == null) 
+                                               throw new ArgumentNullException("providedArgs");
+
+                                       if ((bindingFlags & BindingFlags.GetProperty) != 0)
+                                               // "Can not specify both SetField and GetProperty."
+                                               throw new ArgumentException(("Arg_FldSetPropGet"),"bindingFlags");
+
+                                       if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
+                                               // "Can not specify Set on a Field and Invoke on a method."
+                                               throw new ArgumentException(("Arg_FldSetInvoke"),"bindingFlags");
+                               }
+                               #endregion
+                                               
+                               #region Lookup Field
+                               FieldInfo selFld = null;                
+                               FieldInfo[] flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[];
+
+                               if (flds.Length == 1)
+                               {
+                                       selFld = flds[0];
+                               }
+                               else if (flds.Length > 0)
+                               {
+                                       selFld = binder.BindToField(bindingFlags, flds, IsGetField ? Empty.Value : providedArgs[0], culture);
+                               }
+                               #endregion
+                               
+                               if (selFld != null) 
+                               {
+                                       #region Invocation on a field
+                                       if (selFld.FieldType.IsArray || Object.ReferenceEquals(selFld.FieldType, typeof(System.Array)))
+                                       {
+                                               #region Invocation of an array Field
+                                               int idxCnt;
+
+                                               if ((bindingFlags & BindingFlags.GetField) != 0) 
+                                               {
+                                                       idxCnt = argCnt;
+                                               }
+                                               else
+                                               {
+                                                       idxCnt = argCnt - 1;
+                                               }
+
+                                               if (idxCnt > 0) 
+                                               {
+                                                       // Verify that all of the index values are ints
+                                                       int[] idx = new int[idxCnt];
+                                                       for (int i=0;i<idxCnt;i++) 
+                                                       {
+                                                               try 
+                                                               {
+                                                                       idx[i] = ((IConvertible)providedArgs[i]).ToInt32(null);
+                                                               }
+                                                               catch (InvalidCastException)
+                                                               {
+                                                                       throw new ArgumentException(("Arg_IndexMustBeInt"));
+                                                               }
+                                                       }
+                                                       
+                                                       // Set or get the value...
+                                                       Array a = (Array) selFld.GetValue(target);
+                                                       
+                                                       // Set or get the value in the array
+                                                       if ((bindingFlags & BindingFlags.GetField) != 0) 
+                                                       {
+                                                               return a.GetValue(idx);
+                                                       }
+                                                       else 
+                                                       {
+                                                               a.SetValue(providedArgs[idxCnt],idx);
+                                                               return null;
+                                                       }
+                                               }
+                                               #endregion
+                                       }
+                                       
+                                       if (IsGetField)
+                                       {
+                                               #region Get the field value
+                                               if (argCnt != 0)
+                                                       throw new ArgumentException(("Arg_FldGetArgErr"),"bindingFlags");
+
+                                               return selFld.GetValue(target);
+                                               #endregion
+                                       }
+                                       else
+                                       {
+                                               #region Set the field Value
+                                               if (argCnt != 1)
+                                                       throw new ArgumentException(("Arg_FldSetArgErr"),"bindingFlags");
+
+                                               selFld.SetValue(target,providedArgs[0],bindingFlags,binder,culture);
+
+                                               return null;
+                                               #endregion
+                                       }
+                                       #endregion
+                               }
+
+                               if ((bindingFlags & BinderNonFieldGetSet) == 0) 
+                                       throw new MissingFieldException(FullName, name);
+                       }
+                       #endregion
+
+                       #region Caching Logic
+                       /*
+                       bool useCache = false;
+
+                       // Note that when we add something to the cache, we are careful to ensure
+                       // that the actual providedArgs matches the parameters of the method.  Otherwise,
+                       // some default argument processing has occurred.  We don't want anyone
+                       // else with the same (insufficient) number of actual arguments to get a
+                       // cache hit because then they would bypass the default argument processing
+                       // and the invocation would fail.
+                       if (bDefaultBinder && namedParams == null && argCnt < 6)
+                               useCache = true;
+
+                       if (useCache)
+                       {
+                               MethodBase invokeMethod = GetMethodFromCache (name, bindingFlags, argCnt, providedArgs);
+
+                               if (invokeMethod != null)
+                                       return ((MethodInfo) invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
+                       }
+                       */
+                       #endregion
+
+                       #region Property PreConditions
+                       // @Legacy - This is RTM behavior
+                       bool isGetProperty = (bindingFlags & BindingFlags.GetProperty) != 0;
+                       bool isSetProperty = (bindingFlags & BindingFlags.SetProperty) != 0;
+
+                       if (isGetProperty || isSetProperty) 
+                       {
+                               #region Preconditions
+                               if (isGetProperty)
+                               {
+                                       if (isSetProperty)
+                                               throw new ArgumentException(("Arg_PropSetGet"), "bindingFlags");
+                               }
+                               else
+                               {
+                                       if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
+                                               throw new ArgumentException(("Arg_PropSetInvoke"), "bindingFlags");
+                               }
+                               #endregion
+                       }
+                       #endregion
+
+                       MethodInfo[] finalists = null;
+                       MethodInfo finalist = null;
+
+                       #region BindingFlags.InvokeMethod
+                       if ((bindingFlags & BindingFlags.InvokeMethod) != 0) 
+                       {
+                               #region Lookup Methods
+                               MethodInfo[] semiFinalists = GetMember(name, MemberTypes.Method, bindingFlags) as MethodInfo[];
+                               List<MethodInfo> results = null;
+                               
+                               for(int i = 0; i < semiFinalists.Length; i ++)
+                               {
+                                       MethodInfo semiFinalist = semiFinalists[i];
+
+                                       if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
+                                               continue;
+                                       
+                                       if (finalist == null)
+                                       {
+                                               finalist = semiFinalist;
+                                       }
+                                       else
+                                       {
+                                               if (results == null)
+                                               {
+                                                       results = new List<MethodInfo>(semiFinalists.Length);
+                                                       results.Add(finalist);
+                                               }
+
+                                               results.Add(semiFinalist);
+                                       }
+                               }
+                               
+                               if (results != null)
+                               {
+                                       finalists = new MethodInfo[results.Count];
+                                       results.CopyTo(finalists);
+                               }
+                               #endregion
+                       }
+                       #endregion
+                       
+                       #region BindingFlags.GetProperty or BindingFlags.SetProperty
+                       if (finalist == null && isGetProperty || isSetProperty) 
+                       {
+                               #region Lookup Property
+                               PropertyInfo[] semiFinalists = GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[];                        
+                               List<MethodInfo> results = null;
+
+                               for(int i = 0; i < semiFinalists.Length; i ++)
+                               {
+                                       MethodInfo semiFinalist = null;
+
+                                       if (isSetProperty)
+                                       {
+                                               semiFinalist = semiFinalists[i].GetSetMethod(true);
+                                       }
+                                       else
+                                       {
+                                               semiFinalist = semiFinalists[i].GetGetMethod(true);
+                                       }
+
+                                       if (semiFinalist == null)
+                                               continue;
+
+                                       if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
+                                               continue;
+                                       
+                                       if (finalist == null)
+                                       {
+                                               finalist = semiFinalist;
+                                       }
+                                       else
+                                       {
+                                               if (results == null)
+                                               {
+                                                       results = new List<MethodInfo>(semiFinalists.Length);
+                                                       results.Add(finalist);
+                                               }
+
+                                               results.Add(semiFinalist);
+                                       }
+                               }
+
+                               if (results != null)
+                               {
+                                       finalists = new MethodInfo[results.Count];
+                                       results.CopyTo(finalists);
+                               }
+                               #endregion
+                       }
+                       #endregion
+
+                       if (finalist != null) 
+                       {
+                               #region Invoke
+                               if (finalists == null && 
+                                       argCnt == 0 && 
+                                       finalist.GetParametersNoCopy().Length == 0 && 
+                                       (bindingFlags & BindingFlags.OptionalParamBinding) == 0)
+                               {
+                                       //if (useCache && argCnt == props[0].GetParameters().Length)
+                                       //    AddMethodToCache(name, bindingFlags, argCnt, providedArgs, props[0]);
+
+                                       return finalist.Invoke(target, bindingFlags, binder, providedArgs, culture);
+                               }
+                               
+                               if (finalists == null)
+                                       finalists = new MethodInfo[] { finalist };
+
+                               if (providedArgs == null)
+                                               providedArgs = Array.Empty<Object>();
+
+                               Object state = null;
+
+                               
+                               MethodBase invokeMethod = null;
+
+                               try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs, modifiers, culture, namedParams, out state); }
+                               catch(MissingMethodException) { }
+
+                               if (invokeMethod == null)
+                                       throw new MissingMethodException(FullName, name);
+
+                               //if (useCache && argCnt == invokeMethod.GetParameters().Length)
+                               //    AddMethodToCache(name, bindingFlags, argCnt, providedArgs, invokeMethod);
+
+                               Object result = ((MethodInfo)invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
+
+                               if (state != null)
+                                       binder.ReorderArgumentArray(ref providedArgs, state);
+
+                               return result;
+                               #endregion
+                       }
+                       
+                       throw new MissingMethodException(FullName, name);
+               }
+
+               private void CreateInstanceCheckThis()
+               {
+                       if (ContainsGenericParameters)
+                               throw new ArgumentException(
+                                       SR.Format("Acc_CreateGenericEx", this));
+
+                       Type elementType = this.GetRootElementType();
+
+                       if (Object.ReferenceEquals(elementType, typeof(ArgIterator)))
+                               throw new NotSupportedException(("Acc_CreateArgIterator"));
+
+                       if (Object.ReferenceEquals(elementType, typeof(void)))
+                               throw new NotSupportedException(("Acc_CreateVoid"));
+               }
+
+               internal Object CreateInstanceImpl(
+                       BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture
+                       )
+               {
+                       CreateInstanceCheckThis();
+                       
+                       Object server = null;
+
+                       try
+                       {
+                               try
+                               {
+                                       // Store the activation attributes in thread local storage.
+                                       // These attributes are later picked up by specialized 
+                                       // activation services like remote activation services to
+                                       // influence the activation.
+                                       
+                                       if (args == null)
+                                               args = Array.Empty<Object> ();
+
+                                       int argCnt = args.Length;
+
+                                       // Without a binder we need to do use the default binder...
+                                       if (binder == null)
+                                               binder = DefaultBinder;
+
+                                       // deal with the __COMObject case first. It is very special because from a reflection point of view it has no ctors
+                                       // so a call to GetMemberCons would fail
+                                       bool publicOnly = (bindingAttr & BindingFlags.NonPublic) == 0;
+                                       bool wrapExceptions = (bindingAttr & BindingFlags.DoNotWrapExceptions) == 0;
+                                       if (argCnt == 0 && (bindingAttr & BindingFlags.Public) != 0 && (bindingAttr & BindingFlags.Instance) != 0
+                                               && (IsGenericCOMObjectImpl() || IsValueType)) 
+                                       {
+                                               server = CreateInstanceDefaultCtor(publicOnly, false, true, wrapExceptions);
+                                       }
+                                       else 
+                                       {
+                                               ConstructorInfo[] candidates = GetConstructors(bindingAttr);
+                                               List<MethodBase> matches = new List<MethodBase>(candidates.Length);
+
+                                               // We cannot use Type.GetTypeArray here because some of the args might be null
+                                               Type[] argsType = new Type[argCnt];
+                                               for (int i = 0; i < argCnt; i++)
+                                               {
+                                                       if (args[i] != null)
+                                                       {
+                                                               argsType[i] = args[i].GetType();
+                                                       }
+                                               }
+
+                                               for(int i = 0; i < candidates.Length; i ++)
+                                               {
+                                                       if (FilterApplyConstructorInfo((RuntimeConstructorInfo)candidates[i], bindingAttr, CallingConventions.Any, argsType))
+                                                               matches.Add(candidates[i]);
+                                               }
+
+                                               MethodBase[] cons = new MethodBase[matches.Count];
+                                               matches.CopyTo(cons);
+                                               if (cons != null && cons.Length == 0)
+                                                       cons = null;
+
+                                               if (cons == null) 
+                                               {
+                                                       // Null out activation attributes before throwing exception
+                                                       throw new MissingMethodException(SR.Format("MissingConstructor_Name", FullName));
+                                               }
+
+                                               MethodBase invokeMethod;
+                                               Object state = null;
+
+                                               try
+                                               {
+                                                       invokeMethod = binder.BindToMethod(bindingAttr, cons, ref args, null, culture, null, out state);
+                                               }
+                                               catch (MissingMethodException) { invokeMethod = null; }
+
+                                               if (invokeMethod == null)
+                                               {
+                                                       throw new MissingMethodException(SR.Format("MissingConstructor_Name", FullName));
+                                               }
+
+                                               if (invokeMethod.GetParametersNoCopy().Length == 0)
+                                               {
+                                                       if (args.Length != 0)
+                                                       {
+
+                                                               throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, 
+                                                                       ("NotSupported_CallToVarArg")));
+                                                       }
+
+                                                       // fast path??
+                                                       server = Activator.CreateInstance(this, nonPublic: true, wrapExceptions: wrapExceptions);
+                                               }
+                                               else
+                                               {
+                                                       server = ((ConstructorInfo)invokeMethod).Invoke(bindingAttr, binder, args, culture);
+
+                                                       if (state != null)
+                                                               binder.ReorderArgumentArray(ref args, state);
+                                               }
+                                       }
+                               }
+                               finally
+                               {
+                               }
+                       }
+                       catch (Exception)
+                       {
+                               throw;
+                       }
+                       
+                       return server;
+               }
+
+               [DebuggerStepThroughAttribute]
+               [Diagnostics.DebuggerHidden]
+               internal Object CreateInstanceDefaultCtor(bool publicOnly, bool skipCheckThis, bool fillCache, bool wrapExceptions
+                       )
+               {
+                       if (IsByRefLike)
+                               throw new NotSupportedException (SR.NotSupported_ByRefLike);
+
+                       return CreateInstanceSlow(publicOnly, wrapExceptions, skipCheckThis, fillCache);
+               }
+
+               internal static BindingFlags FilterPreCalculate(bool isPublic, bool isInherited, bool isStatic)
+               {
+                       BindingFlags bindingFlags = isPublic ? BindingFlags.Public : BindingFlags.NonPublic;
+
+                       if (isInherited) 
+                       {   
+                               // We arrange things so the DeclaredOnly flag means "include inherited members"
+                               bindingFlags |= BindingFlags.DeclaredOnly; 
+
+                               if (isStatic)
+                               {
+                                       bindingFlags |= BindingFlags.Static | BindingFlags.FlattenHierarchy;
+                               }
+                               else
+                               {
+                                       bindingFlags |= BindingFlags.Instance;
+                               }
+                       }
+                       else
+                       {
+                               if (isStatic)
+                               {
+                                       bindingFlags |= BindingFlags.Static;
+                               }
+                               else
+                               {
+                                       bindingFlags |= BindingFlags.Instance;
+                               }
+                       }
+
+                       return bindingFlags;
+               }
+
+               // Calculate prefixLookup, ignoreCase, and listType for use by GetXXXCandidates
+               private static void FilterHelper(
+                       BindingFlags bindingFlags, ref string name, bool allowPrefixLookup, out bool prefixLookup, 
+                       out bool ignoreCase, out MemberListType listType)
+               {
+                       prefixLookup = false;
+                       ignoreCase = false;
+
+                       if (name != null)
+                       {
+                               if ((bindingFlags & BindingFlags.IgnoreCase) != 0)
+                               {
+                                       name = name.ToLower(CultureInfo.InvariantCulture);
+                                       ignoreCase = true;
+                                       listType = MemberListType.CaseInsensitive;
+                               }
+                               else
+                               {
+                                       listType = MemberListType.CaseSensitive;
+                               }
+
+                               if (allowPrefixLookup && name.EndsWith("*", StringComparison.Ordinal))
+                               {
+                                       // We set prefixLookup to true if name ends with a "*".
+                                       // We will also set listType to All so that all members are included in 
+                                       // the candidates which are later filtered by FilterApplyPrefixLookup.
+                                       name = name.Substring(0, name.Length - 1);
+                                       prefixLookup = true;
+                                       listType = MemberListType.All;
+                               }
+                       }
+                       else
+                       {
+                               listType = MemberListType.All;
+                       }
+               }
+
+               // Used by the singular GetXXX APIs (Event, Field, Interface, NestedType) where prefixLookup is not supported.
+               private static void FilterHelper(BindingFlags bindingFlags, ref string name, out bool ignoreCase, out MemberListType listType)
+               {
+                       bool prefixLookup;
+                       FilterHelper(bindingFlags, ref name, false, out prefixLookup, out ignoreCase, out listType);
+               }
+
+               // Only called by GetXXXCandidates, GetInterfaces, and GetNestedTypes when FilterHelper has set "prefixLookup" to true.
+               // Most of the plural GetXXX methods allow prefix lookups while the singular GetXXX methods mostly do not.
+               private static bool FilterApplyPrefixLookup(MemberInfo memberInfo, string name, bool ignoreCase)
+               {
+                       if (ignoreCase)
+                       {
+                               if (!memberInfo.Name.StartsWith(name, StringComparison.OrdinalIgnoreCase))
+                                       return false;
+                       }
+                       else
+                       {
+                               if (!memberInfo.Name.StartsWith(name, StringComparison.Ordinal))
+                                       return false;
+                       }            
+
+                       return true;
+               }
+
+
+               // Used by FilterApplyType to perform all the filtering based on name and BindingFlags
+               private static bool FilterApplyBase(
+                       MemberInfo memberInfo, BindingFlags bindingFlags, bool isPublic, bool isNonProtectedInternal, bool isStatic,
+                       string name, bool prefixLookup)
+               {
+
+                       #region Filter by Public & Private
+                       if (isPublic)
+                       {
+                               if ((bindingFlags & BindingFlags.Public) == 0)
+                                       return false;
+                       }
+                       else
+                       {
+                               if ((bindingFlags & BindingFlags.NonPublic) == 0)
+                                       return false;
+                       }
+                       #endregion
+
+                       bool isInherited = !Object.ReferenceEquals(memberInfo.DeclaringType, memberInfo.ReflectedType);
+
+                       #region Filter by DeclaredOnly
+                       if ((bindingFlags & BindingFlags.DeclaredOnly) != 0 && isInherited)
+                               return false;
+                       #endregion
+
+                       #region Filter by Static & Instance
+                       if (memberInfo.MemberType != MemberTypes.TypeInfo && 
+                               memberInfo.MemberType != MemberTypes.NestedType)
+                       {
+                               if (isStatic)
+                               {
+                                       if ((bindingFlags & BindingFlags.FlattenHierarchy) == 0 && isInherited)
+                                               return false;
+
+                                       if ((bindingFlags & BindingFlags.Static) == 0)
+                                               return false;
+                               }
+                               else
+                               {
+                                       if ((bindingFlags & BindingFlags.Instance) == 0)
+                                               return false;
+                               }
+                       }
+                       #endregion
+
+                       #region Filter by name wrt prefixLookup and implicitly by case sensitivity
+                       if (prefixLookup == true)
+                       {
+                               if (!FilterApplyPrefixLookup(memberInfo, name, (bindingFlags & BindingFlags.IgnoreCase) != 0))
+                                       return false;
+                       }
+                       #endregion
+
+                       #region Asymmetries
+                       // @Asymmetry - Internal, inherited, instance, non-protected, non-virtual, non-abstract members returned 
+                       //              iff BindingFlags !DeclaredOnly, Instance and Public are present except for fields
+                       if (((bindingFlags & BindingFlags.DeclaredOnly) == 0) &&        // DeclaredOnly not present
+                                isInherited  &&                                            // Is inherited Member
+       
+                               (isNonProtectedInternal) &&                                 // Is non-protected internal member
+                               ((bindingFlags & BindingFlags.NonPublic) != 0) &&           // BindingFlag.NonPublic present 
+
+                               (!isStatic) &&                                              // Is instance member
+                               ((bindingFlags & BindingFlags.Instance) != 0))              // BindingFlag.Instance present 
+                       {
+                               MethodInfo methodInfo = memberInfo as MethodInfo;
+
+                               if (methodInfo == null)
+                                       return false;
+
+                               if (!methodInfo.IsVirtual && !methodInfo.IsAbstract)
+                                       return false;
+                       }
+                       #endregion
+
+                       return true;
+               }
+
+
+               // Used by GetInterface and GetNestedType(s) which don't need parameter type filtering.
+               private static bool FilterApplyType(
+                       Type type, BindingFlags bindingFlags, string name, bool prefixLookup, string ns)
+               {
+                       bool isPublic = type.IsNestedPublic || type.IsPublic;
+                       bool isStatic = false;
+
+                       if (!RuntimeType.FilterApplyBase(type, bindingFlags, isPublic, type.IsNestedAssembly, isStatic, name, prefixLookup))
+                               return false;
+
+                       if (ns != null && ns != type.Namespace)
+                               return false;
+
+                       return true;
+               }
+
+
+               private static bool FilterApplyMethodInfo(
+                       RuntimeMethodInfo method, BindingFlags bindingFlags, CallingConventions callConv, Type[] argumentTypes)
+               {
+                       // Optimization: Pre-Calculate the method binding flags to avoid casting.
+                       return FilterApplyMethodBase(method, method.BindingFlags, bindingFlags, callConv, argumentTypes);
+               }
+
+               private static bool FilterApplyConstructorInfo(
+                       RuntimeConstructorInfo constructor, BindingFlags bindingFlags, CallingConventions callConv, Type[] argumentTypes)
+               {
+                       // Optimization: Pre-Calculate the method binding flags to avoid casting.
+                       return FilterApplyMethodBase(constructor, constructor.BindingFlags, bindingFlags, callConv, argumentTypes);
+               }
+
+               // Used by GetMethodCandidates/GetConstructorCandidates, InvokeMember, and CreateInstanceImpl to perform the necessary filtering.
+               // Should only be called by FilterApplyMethodInfo and FilterApplyConstructorInfo.
+               private static bool FilterApplyMethodBase(
+                       MethodBase methodBase, BindingFlags methodFlags, BindingFlags bindingFlags, CallingConventions callConv, Type[] argumentTypes)
+               {
+                       bindingFlags ^= BindingFlags.DeclaredOnly;
+
+                       #region Check CallingConvention
+                       if ((callConv & CallingConventions.Any) == 0)
+                       {
+                               if ((callConv & CallingConventions.VarArgs) != 0 && 
+                                       (methodBase.CallingConvention & CallingConventions.VarArgs) == 0)
+                                       return false;
+
+                               if ((callConv & CallingConventions.Standard) != 0 && 
+                                       (methodBase.CallingConvention & CallingConventions.Standard) == 0)
+                                       return false;
+                       }
+                       #endregion
+
+                       #region If argumentTypes supplied
+                       if (argumentTypes != null)
+                       {
+                               ParameterInfo[] parameterInfos = methodBase.GetParametersNoCopy();
+
+                               if (argumentTypes.Length != parameterInfos.Length)
+                               {
+                                       #region Invoke Member, Get\Set & Create Instance specific case
+                                       // If the number of supplied arguments differs than the number in the signature AND
+                                       // we are not filtering for a dynamic call -- InvokeMethod or CreateInstance -- filter out the method.
+                                       if ((bindingFlags & 
+                                               (BindingFlags.InvokeMethod | BindingFlags.CreateInstance | BindingFlags.GetProperty | BindingFlags.SetProperty)) == 0)
+                                               return false;
+                                       
+                                       bool testForParamArray = false;
+                                       bool excessSuppliedArguments = argumentTypes.Length > parameterInfos.Length;
+
+                                       if (excessSuppliedArguments) 
+                                       { // more supplied arguments than parameters, additional arguments could be vararg
+                                               #region Varargs
+                                               // If method is not vararg, additional arguments can not be passed as vararg
+                                               if ((methodBase.CallingConvention & CallingConventions.VarArgs) == 0)
+                                               {
+                                                       testForParamArray = true;
+                                               }
+                                               else 
+                                               {
+                                                       // If Binding flags did not include varargs we would have filtered this vararg method.
+                                                       // This Invariant established during callConv check.
+                                               }
+                                               #endregion
+                                       }
+                                       else 
+                                       {// fewer supplied arguments than parameters, missing arguments could be optional
+                                               #region OptionalParamBinding
+                                               if ((bindingFlags & BindingFlags.OptionalParamBinding) == 0)
+                                               {
+                                                       testForParamArray = true;
+                                               }
+                                               else
+                                               {
+                                                       // From our existing code, our policy here is that if a parameterInfo 
+                                                       // is optional then all subsequent parameterInfos shall be optional. 
+
+                                                       // Thus, iff the first parameterInfo is not optional then this MethodInfo is no longer a canidate.
+                                                       if (!parameterInfos[argumentTypes.Length].IsOptional)
+                                                               testForParamArray = true;
+                                               }
+                                               #endregion
+                                       }
+
+                                       #region ParamArray
+                                       if (testForParamArray)
+                                       {
+                                               if  (parameterInfos.Length == 0)
+                                                       return false;
+
+                                               // The last argument of the signature could be a param array. 
+                                               bool shortByMoreThanOneSuppliedArgument = argumentTypes.Length < parameterInfos.Length - 1;
+
+                                               if (shortByMoreThanOneSuppliedArgument)
+                                                       return false;
+
+                                               ParameterInfo lastParameter = parameterInfos[parameterInfos.Length - 1];
+
+                                               if (!lastParameter.ParameterType.IsArray)
+                                                       return false;
+
+                                               if (!lastParameter.IsDefined(typeof(ParamArrayAttribute), false))
+                                                       return false;
+                                       }
+                                       #endregion
+
+                                       #endregion
+                               }
+                               else
+                               {
+                                       #region Exact Binding
+                                       if ((bindingFlags & BindingFlags.ExactBinding) != 0)
+                                       {
+                                               // Legacy behavior is to ignore ExactBinding when InvokeMember is specified.
+                                               // Why filter by InvokeMember? If the answer is we leave this to the binder then why not leave
+                                               // all the rest of this  to the binder too? Further, what other semanitc would the binder
+                                               // use for BindingFlags.ExactBinding besides this one? Further, why not include CreateInstance 
+                                               // in this if statement? That's just InvokeMethod with a constructor, right?
+                                               if ((bindingFlags & (BindingFlags.InvokeMethod)) == 0)
+                                               {
+                                                       for(int i = 0; i < parameterInfos.Length; i ++)
+                                                       {
+                                                               // a null argument type implies a null arg which is always a perfect match
+                                                               if ((object)argumentTypes[i] != null && !argumentTypes[i].MatchesParameterTypeExactly(parameterInfos[i]))
+                                                                       return false;
+                                                       }
+                                               }
+                                       }
+                                       #endregion
+                               }
+                       }
+                       #endregion
+               
+                       return true;
+               }
+
+               private ListBuilder<MethodInfo> GetMethodCandidates(
+                       String name, BindingFlags bindingAttr, CallingConventions callConv,
+                       Type[] types, int genericParamCount, bool allowPrefixLookup)
+               {
+                       bool prefixLookup, ignoreCase;
+                       MemberListType listType;
+                       RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
+
+                       RuntimeMethodInfo[] cache = GetMethodsByName (name, bindingAttr, listType, this);
+                       ListBuilder<MethodInfo> candidates = new ListBuilder<MethodInfo>(cache.Length);
+
+                       for (int i = 0; i < cache.Length; i++)
+                       {
+                               RuntimeMethodInfo methodInfo = cache[i];
+                               if (genericParamCount != -1) {
+                                       bool is_generic = methodInfo.IsGenericMethod;
+                                       if (genericParamCount == 0 && is_generic)
+                                               continue;
+                                       else if (genericParamCount > 0 && !is_generic)
+                                               continue;
+                                       var args = methodInfo.GetGenericArguments ();
+                                       if (args.Length != genericParamCount)
+                                               continue;
+                               }
+                               if (FilterApplyMethodInfo(methodInfo, bindingAttr, callConv, types) &&
+                                       (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(methodInfo, name, ignoreCase)))
+                               {
+                                       candidates.Add(methodInfo);
+                               }
+                       }
+
+                       return candidates;
+               }
+
+               private ListBuilder<ConstructorInfo> GetConstructorCandidates(
+                       string name, BindingFlags bindingAttr, CallingConventions callConv, 
+                       Type[] types, bool allowPrefixLookup)
+               {
+                       bool prefixLookup, ignoreCase;
+                       MemberListType listType;
+                       RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
+
+                       if (!string.IsNullOrEmpty (name) && name != ConstructorInfo.ConstructorName && name != ConstructorInfo.TypeConstructorName)
+                               return new ListBuilder<ConstructorInfo> (0);
+                       RuntimeConstructorInfo[] cache = GetConstructors_internal (bindingAttr, this);
+                       ListBuilder<ConstructorInfo> candidates = new ListBuilder<ConstructorInfo>(cache.Length);
+                       for (int i = 0; i < cache.Length; i++)
+                       {
+                               RuntimeConstructorInfo constructorInfo = cache[i];
+                               if (FilterApplyConstructorInfo(constructorInfo, bindingAttr, callConv, types) &&
+                                       (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(constructorInfo, name, ignoreCase)))
+                               {                    
+                                       candidates.Add(constructorInfo);
+                               }
+                       }
+
+                       return candidates;
+               }
+
+
+               private ListBuilder<PropertyInfo> GetPropertyCandidates(
+                       String name, BindingFlags bindingAttr, Type[] types, bool allowPrefixLookup)
+               {
+                       bool prefixLookup, ignoreCase;
+                       MemberListType listType;
+                       RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
+
+                       RuntimePropertyInfo[] cache = GetPropertiesByName (name, bindingAttr, listType, this);
+                       bindingAttr ^= BindingFlags.DeclaredOnly;
+
+                       ListBuilder<PropertyInfo> candidates = new ListBuilder<PropertyInfo>(cache.Length);
+                       for (int i = 0; i < cache.Length; i++)
+                       {
+                               RuntimePropertyInfo propertyInfo = cache[i];
+                               if ((bindingAttr & propertyInfo.BindingFlags) == propertyInfo.BindingFlags &&
+                                       (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(propertyInfo, name, ignoreCase)) &&
+                                       (types == null || (propertyInfo.GetIndexParameters().Length == types.Length)))
+                               {
+                                       candidates.Add(propertyInfo);
+                               }
+                       }
+
+                       return candidates;
+               }
+
+               private ListBuilder<EventInfo> GetEventCandidates(String name, BindingFlags bindingAttr, bool allowPrefixLookup)
+               {
+                       bool prefixLookup, ignoreCase;
+                       MemberListType listType;
+                       RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
+
+                       RuntimeEventInfo[] cache = GetEvents_internal (name, bindingAttr, listType, this);
+                       bindingAttr ^= BindingFlags.DeclaredOnly;
+
+                       ListBuilder<EventInfo> candidates = new ListBuilder<EventInfo>(cache.Length);
+                       for (int i = 0; i < cache.Length; i++)
+                       {
+                               RuntimeEventInfo eventInfo = cache[i];
+                               if ((bindingAttr & eventInfo.BindingFlags) == eventInfo.BindingFlags &&
+                                       (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(eventInfo, name, ignoreCase)))
+                               {
+                                       candidates.Add(eventInfo);
+                               }
+                       }
+
+                       return candidates;
+               }
+
+               private ListBuilder<FieldInfo> GetFieldCandidates(String name, BindingFlags bindingAttr, bool allowPrefixLookup)
+               {
+                       bool prefixLookup, ignoreCase;
+                       MemberListType listType;
+                       RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
+
+                       RuntimeFieldInfo[] cache = GetFields_internal (name, bindingAttr, listType, this);
+                       bindingAttr ^= BindingFlags.DeclaredOnly;
+
+                       ListBuilder<FieldInfo> candidates = new ListBuilder<FieldInfo>(cache.Length);
+                       for (int i = 0; i < cache.Length; i++)
+                       {
+                               RuntimeFieldInfo fieldInfo = cache[i];
+                               if ((bindingAttr & fieldInfo.BindingFlags) == fieldInfo.BindingFlags && 
+                                       (!prefixLookup || FilterApplyPrefixLookup(fieldInfo, name, ignoreCase)))
+                               {
+                                       candidates.Add(fieldInfo);
+                               }
+                       }
+
+                       return candidates;
+               }
+
+               private ListBuilder<Type> GetNestedTypeCandidates(String fullname, BindingFlags bindingAttr, bool allowPrefixLookup)
+               {
+                       bool prefixLookup, ignoreCase;
+                       bindingAttr &= ~BindingFlags.Static;
+                       string name, ns;
+                       MemberListType listType;
+                       SplitName(fullname, out name, out ns);            
+                       RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
+
+                       RuntimeType[] cache = GetNestedTypes_internal (name, bindingAttr, listType);
+                       ListBuilder<Type> candidates = new ListBuilder<Type>(cache.Length);
+                       for (int i = 0; i < cache.Length; i++)
+                       {
+                               RuntimeType nestedClass = cache[i];
+                               if (RuntimeType.FilterApplyType(nestedClass, bindingAttr, name, prefixLookup, ns))
+                               {
+                                       candidates.Add(nestedClass);
+                               }
+                       }
+
+                       return candidates;
+               }
+
+               internal static RuntimeType GetType(String typeName, bool throwOnError, bool ignoreCase, bool reflectionOnly,
+                       ref StackCrawlMark stackMark)
+               {
+                       if (typeName == null)
+                               throw new ArgumentNullException("typeName");
+
+                       return RuntimeTypeHandle.GetTypeByName(
+                               typeName, throwOnError, ignoreCase, reflectionOnly, ref stackMark, false);
+               }
+       }
+
+       internal enum TypeNameKind
+       {
+               Name,
+               ToString,
+               SerializationName,
+               FullName,
+       }
+
+       // Keep this in sync with FormatFlags defined in typestring.h
+       enum TypeNameFormatFlags
+       {
+               FormatBasic         = 0x00000000, // Not a bitmask, simply the tersest flag settings possible
+               FormatNamespace     = 0x00000001, // Include namespace and/or enclosing class names in type names
+               FormatFullInst      = 0x00000002, // Include namespace and assembly in generic types (regardless of other flag settings)
+               FormatAssembly      = 0x00000004, // Include assembly display name in type names
+               FormatSignature     = 0x00000008, // Include signature in method names
+               FormatNoVersion     = 0x00000010, // Suppress version and culture information in all assembly names
+               FormatAngleBrackets = 0x00000040, // Whether generic types are C<T> or C[T]
+               FormatStubInfo      = 0x00000080, // Include stub info like {unbox-stub}
+               FormatGenericParam  = 0x00000100, // Use !name and !!name for generic type and method parameters
+
+               // If we want to be able to distinguish between overloads whose parameter types have the same name but come from different assemblies,
+               // we can add FormatAssembly | FormatNoVersion to FormatSerialization. But we are omitting it because it is not a useful scenario
+               // and including the assembly name will normally increase the size of the serialized data and also decrease the performance.
+               FormatSerialization = FormatNamespace |
+                                                         FormatGenericParam |
+                                                         FormatFullInst
+       }       
 }