RtType.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / clr / src / BCL / System / RtType.cs / 1 / RtType.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 

 
using System; 
using System.Reflection;
using System.Runtime.ConstrainedExecution; 
using System.Globalization;
using System.Threading;
using System.Diagnostics;
using System.Security.Permissions; 
using System.Collections;
using System.Collections.Generic; 
using System.Runtime.Serialization; 
using System.Runtime.CompilerServices;
using System.Security; 
using System.Text;
using System.Reflection.Emit;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Proxies; 
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Activation; 
using MdSigCallingConvention = System.Signature.MdSigCallingConvention; 
using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
using System.Runtime.InteropServices; 
using DebuggerStepThroughAttribute = System.Diagnostics.DebuggerStepThroughAttribute;
using MdToken = System.Reflection.MetadataToken;

namespace System 
{
    // this is a work around to get the concept of a calli. It's not as fast but it would be interesting to 
    // see how it compares to the current implementation. 
    // This delegate will disappear at some point in favor of calli
 
    internal delegate void CtorDelegate(Object instance);

    [Serializable()]
    internal class RuntimeType : Type, ISerializable, ICloneable 
    {
        #region Definitions 
 
        [Serializable()]
        internal class RuntimeTypeCache 
        {
            #region Definitions
            internal enum WhatsCached
            { 
                Nothing         = 0x0,
                EnclosingType   = 0x1, 
            } 

            internal enum CacheType 
            {
                Method,
                Constructor,
                Field, 
                Property,
                Event, 
                Interface, 
                NestedType
            } 

            // This method serves two purposes, both enabling optimizations in ngen image
            // First, it tells ngen which instantiations of MemberInfoCache to save in the ngen image
            // Second, it ensures MemberInfoCache<*Info>.Insert methods are pre-prepared in the 
            // ngen image, and any runtime preparation that needs to happen, happens in the Prestub
            // worker of Prejitinit_Hack. At runtime we do not really want to execute the Insert methods 
            // here; the calls are present just to fool the CER preparation code into preparing those methods during ngen 
            internal static void Prejitinit_HACK()
            { 
                // make sure this conditional is around everything _including_ the call to
                // PrepareConstrainedRegions, the JIT/NGen just needs to see the callsite
                // somewhere, but the callsite has a link demand which can trip up partially
                // trusted code. 
                if (!s_dontrunhack)
                { 
                    RuntimeHelpers.PrepareConstrainedRegions(); 
                    try
                    { } 
                    finally
                    {
                            MemberInfoCache micrmi = new MemberInfoCache(null);
                            CerArrayList list =null; 
                            micrmi.Insert(ref list, "dummy", MemberListType.All);
 
                            MemberInfoCache micrci = new MemberInfoCache(null); 
                            CerArrayList listc =null;
                            micrci.Insert(ref listc, "dummy", MemberListType.All); 

                            MemberInfoCache micrfi = new MemberInfoCache(null);
                            CerArrayList listf =null;
                            micrfi.Insert(ref listf, "dummy", MemberListType.All); 

                            MemberInfoCache micri = new MemberInfoCache(null); 
                            CerArrayList listi =null; 
                            micri.Insert(ref listi, "dummy", MemberListType.All);
 
                            MemberInfoCache micrpi = new MemberInfoCache(null);
                            CerArrayList listp =null;
                            micrpi.Insert(ref listp, "dummy", MemberListType.All);
 
                            MemberInfoCache micrei = new MemberInfoCache(null);
                            CerArrayList liste =null; 
                            micrei.Insert(ref liste, "dummy", MemberListType.All); 
                    }
                } 
            }

            private struct Filter
            { 
                private Utf8String m_name;
                private MemberListType m_listType; 
 
                public unsafe Filter(byte* pUtf8Name, int cUtf8Name, MemberListType listType)
                { 
                      this.m_name = new Utf8String((void*) pUtf8Name, cUtf8Name);
                      this.m_listType = listType;
                }
 
                public bool Match(Utf8String name)
                { 
                    if (m_listType == MemberListType.CaseSensitive) 
                        return m_name.Equals(name);
                    else if (m_listType == MemberListType.CaseInsensitive) 
                        return m_name.EqualsCaseInsensitive(name);
                    else
                        return true;
                } 
            }
 
            [Serializable()] 
            private class MemberInfoCache where T : MemberInfo
            { 
                #region Static Members

                static MemberInfoCache()
                { 
                    // We need to prepare some code in this class for reliable
                    // execution on a per-instantiation basis. A static class 
                    // constructor is ideal for this since we only need to do 
                    // this once per-instantiation. We can't go through the
                    // normal approach using RuntimeHelpers.PrepareMethod since 
                    // that would involve using reflection and we'd wind back up
                    // here recursively. So we call through an fcall helper
                    // instead. The fcall is on RuntimeType to avoid having an
                    // fcall entry for a nested class (a generic one at that). 
                    // I've no idea if that would work, but I'm pretty sure it
                    // wouldn't. Also we pass in our own base type since using 
                    // the mscorlib binder doesn't work for nested types (I've 
                    // tried that one).
                    PrepareMemberInfoCache(typeof(MemberInfoCache).TypeHandle); 
                }

                #endregion
 
                #region Private Data Members
                // MemberInfo caches 
                private CerHashtable> m_csMemberInfos; 
                private CerHashtable> m_cisMemberInfos;
                private CerArrayList m_root; 
                private bool m_cacheComplete;

                // This is the strong reference back to the cache
                private RuntimeTypeCache m_runtimeTypeCache; 
                #endregion
 
                #region Constructor 
                internal MemberInfoCache(RuntimeTypeCache runtimeTypeCache)
                { 
#if MDA_SUPPORTED
                    Mda.MemberInfoCacheCreation();
#endif
                    m_runtimeTypeCache = runtimeTypeCache; 
                    m_cacheComplete = false;
                } 
 
                internal MethodBase AddMethod(RuntimeTypeHandle declaringType, RuntimeMethodHandle method, CacheType cacheType)
                { 
                    Object list = null;
                    MethodAttributes methodAttributes = method.GetAttributes();
                    bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
                    bool isStatic = (methodAttributes & MethodAttributes.Static) != 0; 
                    bool isInherited = declaringType.Value != ReflectedTypeHandle.Value;
                    BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic); 
                    switch (cacheType) 
                    {
                        case CacheType.Method: 
                            List mlist = new List(1);
                            mlist.Add(new RuntimeMethodInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags));
                            list = mlist;
                            break; 
                        case CacheType.Constructor:
                            List clist = new List(1); 
                            clist.Add(new RuntimeConstructorInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags)); 
                            list = clist;
                            break; 
                    }

                    CerArrayList cerList = new CerArrayList((List)list);
 
                    Insert(ref cerList, null, MemberListType.HandleToInfo);
 
                    return (MethodBase)(object)cerList[0]; 
                }
 
                internal FieldInfo AddField(RuntimeFieldHandle field)
                {
                    // create the runtime field info
                    List list = new List(1); 
                    FieldAttributes fieldAttributes = field.GetAttributes();
                    bool isPublic = (fieldAttributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public; 
                    bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0; 
                    bool isInherited = field.GetApproxDeclaringType().Value != ReflectedTypeHandle.Value;
                    BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic); 
                    list.Add(new RtFieldInfo(field, ReflectedType, m_runtimeTypeCache, bindingFlags));

                    CerArrayList cerList = new CerArrayList((List)(object)list);
                    Insert(ref cerList, null, MemberListType.HandleToInfo); 

                    return (FieldInfo)(object)cerList[0]; 
                } 

                private unsafe CerArrayList Populate(string name, MemberListType listType, CacheType cacheType) 
                {
                    if (name == null || name.Length == 0 ||
                        (cacheType == CacheType.Constructor && name.FirstChar != '.' && name.FirstChar != '*'))
                    { 
                        Filter filter = new Filter(null, 0, listType);
                        List list = null; 
 
                        switch (cacheType)
                        { 
                            case CacheType.Method:
                                list = PopulateMethods(filter) as List;
                                break;
                            case CacheType.Field : 
                                list = PopulateFields(filter) as List;
                                break; 
                            case CacheType.Constructor : 
                                list = PopulateConstructors(filter) as List;
                                break; 
                            case CacheType.Property :
                                list = PopulateProperties(filter) as List;
                                break;
                            case CacheType.Event : 
                                list = PopulateEvents(filter) as List;
                                break; 
                            case CacheType.NestedType : 
                                list = PopulateNestedClasses(filter) as List;
                                break; 
                            case CacheType.Interface :
                                list = PopulateInterfaces(filter) as List;
                                break;
                        } 

                        CerArrayList cerList = new CerArrayList(list); 
 
                        Insert(ref cerList, name, listType);
 
                        return cerList;
                    }
                    else
                    { 
                        fixed (char* pName = name)
                        { 
                            int cUtf8Name = Encoding.UTF8.GetByteCount(pName, name.Length); 
                            byte* pUtf8Name = stackalloc byte[cUtf8Name];
                            Encoding.UTF8.GetBytes(pName, name.Length, pUtf8Name, cUtf8Name); 

                            Filter filter = new Filter(pUtf8Name, cUtf8Name, listType);
                            List list = null;
 
                            switch (cacheType)
                            { 
                                case CacheType.Method: 
                                    list = PopulateMethods(filter) as List;
                                    break; 
                                case CacheType.Field :
                                    list = PopulateFields(filter) as List;
                                    break;
                                case CacheType.Constructor : 
                                    list = PopulateConstructors(filter) as List;
                                    break; 
                                case CacheType.Property : 
                                    list = PopulateProperties(filter) as List;
                                    break; 
                                case CacheType.Event :
                                    list = PopulateEvents(filter) as List;
                                    break;
                                case CacheType.NestedType : 
                                    list = PopulateNestedClasses(filter) as List;
                                    break; 
                                case CacheType.Interface : 
                                    list = PopulateInterfaces(filter) as List;
                                    break; 
                            }

                            CerArrayList cerList = new CerArrayList(list);
 
                            Insert(ref cerList, name, listType);
 
                            return cerList; 
                        }
                    } 
                }

                // May replace the list with a new one if certain cache
                // lookups succeed.  Also, may modify the contents of the list 
                // after merging these new data structures with cached ones.
                [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
                internal void Insert(ref CerArrayList list, string name, MemberListType listType) 
                {
                    bool lockTaken = false; 
                    bool preallocationComplete = false;

                    RuntimeHelpers.PrepareConstrainedRegions();
                    try 
                    {
                        Monitor.ReliableEnter(this, ref lockTaken); 
 
                        if (listType == MemberListType.CaseSensitive)
                        { 
                            if (m_csMemberInfos == null)
                                m_csMemberInfos = new CerHashtable>();
                            else
                                m_csMemberInfos.Preallocate(1); 
                        }
                        else if (listType == MemberListType.CaseInsensitive) 
                        { 
                            if (m_cisMemberInfos == null)
                                m_cisMemberInfos = new CerHashtable>(); 
                            else
                                m_cisMemberInfos.Preallocate(1);
                        }
 
                        if (m_root == null)
                            m_root = new CerArrayList(list.Count); 
                        else 
                            m_root.Preallocate(list.Count);
 
                        preallocationComplete = true;
                    }
                    finally
                    { 
                        try
                        { 
                            if (preallocationComplete) 
                            {
                                if (listType == MemberListType.CaseSensitive) 
                                {
                                    // Ensure we always return a list that has
                                    // been merged with the global list.
                                    CerArrayList cachedList = m_csMemberInfos[name]; 
                                    if (cachedList == null)
                                    { 
                                        MergeWithGlobalList(list); 
                                        m_csMemberInfos[name] = list;
                                    } 
                                    else
                                        list = cachedList;
                                }
                                else if (listType == MemberListType.CaseInsensitive) 
                                {
                                    // Ensure we always return a list that has 
                                    // been merged with the global list. 
                                    CerArrayList cachedList = m_cisMemberInfos[name];
                                    if (cachedList == null) 
                                    {
                                        MergeWithGlobalList(list);
                                        m_cisMemberInfos[name] = list;
                                    } 
                                    else
                                        list = cachedList; 
                                } 
                                else
                                { 
                                    MergeWithGlobalList(list);
                                }

                                if (listType == MemberListType.All) 
                                {
                                    m_cacheComplete = true; 
                                } 
                            }
                        } 
                        finally
                        {
                            if (lockTaken)
                            { 
                                Monitor.Exit(this);
                            } 
                        } 
                    }
                } 

                // Modifies the existing list.
                [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
                private void MergeWithGlobalList(CerArrayList list) 
                {
                    int cachedCount = m_root.Count; 
 
                    for (int i = 0; i < list.Count; i++)
                    { 
                        T newMemberInfo = list[i];
                        T cachedMemberInfo = null;

                        for (int j = 0; j < cachedCount; j++) 
                        {
                            cachedMemberInfo = m_root[j]; 
 
                            if (newMemberInfo.CacheEquals(cachedMemberInfo))
                            { 
                                list.Replace(i, cachedMemberInfo);
                                break;
                            }
                        } 

                        if (list[i] != cachedMemberInfo) 
                            m_root.Add(newMemberInfo); 
                    }
                } 
                #endregion

                #region Population Logic
                private unsafe List PopulateMethods(Filter filter) 
                {
                    List list = new List(); 
 
                    RuntimeTypeHandle declaringTypeHandle = ReflectedTypeHandle;
 
                    bool isInterface =
                        (declaringTypeHandle.GetAttributes() & TypeAttributes.ClassSemanticsMask)
                        == TypeAttributes.Interface;
 
                    if (isInterface)
                    { 
                        #region IsInterface 
                        bool mayNeedInstantiatingStub = declaringTypeHandle.HasInstantiation() && !declaringTypeHandle.IsGenericTypeDefinition();
 
                        foreach (RuntimeMethodHandle methodHandle in declaringTypeHandle.IntroducedMethods)
                        {
                            if (!filter.Match(methodHandle.GetUtf8Name()))
                                continue; 

                            #region Loop through all methods on the interface 
                            ASSERT.CONSISTENCY_CHECK(!methodHandle.IsNullHandle()); 
                            ASSERT.CONSISTENCY_CHECK(LOGIC.IMPLIES(
                                (methodHandle.GetAttributes() & MethodAttributes.RTSpecialName) != 0, 
                                methodHandle.GetName().Equals(".ctor") ||
                                methodHandle.GetName().Equals(".cctor") ||
                                methodHandle.GetName().Equals("IL_STUB")));
                            ASSERT.CONSISTENCY_CHECK((methodHandle.GetAttributes() & MethodAttributes.Abstract) != 0); 
                            ASSERT.CONSISTENCY_CHECK((methodHandle.GetAttributes() & MethodAttributes.Virtual) != 0);
 
                            #region Calculate Binding Flags 
                            MethodAttributes methodAttributes = methodHandle.GetAttributes();
                            bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public; 
                            bool isStatic = (methodAttributes & MethodAttributes.Static) != 0;
                            bool isInherited = false;
                            BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
                            #endregion 

                            if ((methodAttributes & MethodAttributes.RTSpecialName) != 0 || methodHandle.IsILStub()) 
                                continue; 

                            // if it is an instantiated type get the InstantiatedMethodDesc if needed 
                            RuntimeMethodHandle instantiatedHandle = mayNeedInstantiatingStub ?
                                methodHandle.GetInstantiatingStubIfNeeded(declaringTypeHandle) : methodHandle;

                            RuntimeMethodInfo runtimeMethodInfo = new RuntimeMethodInfo( 
                                instantiatedHandle, declaringTypeHandle, m_runtimeTypeCache, methodAttributes, bindingFlags);
 
                            list.Add(runtimeMethodInfo); 
                            #endregion
                        } 
                        #endregion
                    }
                    else
                    { 
                        #region IsClass or GenericParameter
                        while(declaringTypeHandle.IsGenericVariable()) 
                            declaringTypeHandle = declaringTypeHandle.GetRuntimeType().BaseType.GetTypeHandleInternal(); 

                        bool* overrides = stackalloc bool[declaringTypeHandle.GetNumVirtuals()]; 
                        bool isValueType = declaringTypeHandle.GetRuntimeType().IsValueType;

                        while(!declaringTypeHandle.IsNullHandle())
                        { 
                            bool mayNeedInstantiatingStub = declaringTypeHandle.HasInstantiation() &&
                                !declaringTypeHandle.IsGenericTypeDefinition(); 
 
                            int vtableSlots = declaringTypeHandle.GetNumVirtuals();
 
                            foreach (RuntimeMethodHandle methodHandle in declaringTypeHandle.IntroducedMethods)
                            {
                                if (!filter.Match(methodHandle.GetUtf8Name()))
                                    continue; 

                                #region Loop through all methods on the current type 
                                ASSERT.CONSISTENCY_CHECK(!methodHandle.IsNullHandle()); 

                                MethodAttributes methodAttributes = methodHandle.GetAttributes(); 
                                MethodAttributes methodAccess = methodAttributes & MethodAttributes.MemberAccessMask;

                                #region Continue if this is a constructor
                                ASSERT.CONSISTENCY_CHECK( 
                                    LOGIC.IMPLIES((methodHandle.GetAttributes() & MethodAttributes.RTSpecialName) != 0,
                                    methodHandle.GetName().Equals(".ctor") || 
                                    methodHandle.GetName().Equals(".cctor") || 
                                    methodHandle.GetName().Equals("IL_STUB") ));
 
                                if ((methodAttributes & MethodAttributes.RTSpecialName) != 0 || methodHandle.IsILStub())
                                    continue;
                                #endregion
 
                                #region Continue if this is a private declared on a base type
                                bool isVirtual = false; 
                                int methodSlot = 0; 
                                if ((methodAttributes & MethodAttributes.Virtual) != 0)
                                { 
                                    // only virtual if actually in the vtableslot range, but GetSlot will
                                    // assert if an EnC method, which can't be virtual, so narrow down first
                                    // before calling GetSlot
                                    methodSlot = methodHandle.GetSlot(); 
                                    isVirtual = (methodSlot < vtableSlots);
                                } 
                                bool isPrivate = methodAccess == MethodAttributes.Private; 
                                bool isPrivateVirtual = isVirtual & isPrivate;
                                bool isInherited = declaringTypeHandle.Value != ReflectedTypeHandle.Value; 
                                if (isInherited && isPrivate && !isPrivateVirtual)
                                    continue;
                                #endregion
 
                                #region Continue if this is a virtual and is already overridden
                                if (isVirtual) 
                                { 
                                    ASSERT.CONSISTENCY_CHECK(
                                        (methodAttributes & MethodAttributes.Abstract) != 0 || 
                                        (methodAttributes & MethodAttributes.Virtual) != 0 ||
                                        methodHandle.GetDeclaringType().Value != declaringTypeHandle.Value);

                                    if (overrides[methodSlot] == true) 
                                        continue;
 
                                    overrides[methodSlot] = true; 
                                }
                                else if (isValueType) 
                                {
                                    if ((methodAttributes & (MethodAttributes.Virtual | MethodAttributes.Abstract)) != 0)
                                        continue;
                                } 
                                else
                                { 
                                    ASSERT.CONSISTENCY_CHECK((methodAttributes & (MethodAttributes.Virtual | MethodAttributes.Abstract)) == 0); 
                                }
                                #endregion 

                                #region Calculate Binding Flags
                                bool isPublic = methodAccess == MethodAttributes.Public;
                                bool isStatic = (methodAttributes & MethodAttributes.Static) != 0; 
                                BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
                                #endregion 
 
                                // if it is an instantiated type get the InstantiatedMethodDesc if needed
                                RuntimeMethodHandle instantiatedHandle = mayNeedInstantiatingStub ? 
                                    methodHandle.GetInstantiatingStubIfNeeded(declaringTypeHandle) : methodHandle;

                                RuntimeMethodInfo runtimeMethodInfo = new RuntimeMethodInfo(
                                    instantiatedHandle, declaringTypeHandle, m_runtimeTypeCache, methodAttributes, bindingFlags); 

                                list.Add(runtimeMethodInfo); 
                                #endregion 
                            }
 
                            declaringTypeHandle = declaringTypeHandle.GetBaseTypeHandle();
                        }
                        #endregion
                    } 

                    return list; 
                } 

                private List PopulateConstructors(Filter filter) 
                {
                    List list = new List();

                    if (ReflectedType.IsGenericParameter) 
                    {
                        return list; 
                    } 

                    RuntimeTypeHandle declaringTypeHandle = ReflectedTypeHandle; 

                    bool mayNeedInstantiatingStub = declaringTypeHandle.HasInstantiation() &&
                        !declaringTypeHandle.IsGenericTypeDefinition();
 
                    foreach (RuntimeMethodHandle methodHandle in declaringTypeHandle.IntroducedMethods)
                    { 
                        if (!filter.Match(methodHandle.GetUtf8Name())) 
                            continue;
 
                        MethodAttributes methodAttributes = methodHandle.GetAttributes();

                        ASSERT.CONSISTENCY_CHECK(!methodHandle.IsNullHandle());
/* 
                        ASSERT.CONSISTENCY_
 
 

 
*/

                        if ((methodAttributes & MethodAttributes.RTSpecialName) == 0)
                            continue; 

                        if (methodHandle.IsILStub()) 
                            continue; 

                        // Constructors should not be virtual or abstract 
                        ASSERT.CONSISTENCY_CHECK(
                            (methodAttributes & MethodAttributes.Abstract) == 0 &&
                            (methodAttributes & MethodAttributes.Virtual) == 0);
 
                        #region Calculate Binding Flags
                        bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public; 
                        bool isStatic = (methodAttributes & MethodAttributes.Static) != 0; 
                        bool isInherited = false;
                        BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic); 
                        #endregion

                        // if it is an instantiated type get the InstantiatedMethodDesc if needed
                        RuntimeMethodHandle instantiatedHandle = mayNeedInstantiatingStub ? 
                            methodHandle.GetInstantiatingStubIfNeeded(declaringTypeHandle) : methodHandle;
 
                        RuntimeConstructorInfo runtimeConstructorInfo = 
                            new RuntimeConstructorInfo(instantiatedHandle, ReflectedTypeHandle, m_runtimeTypeCache, methodAttributes, bindingFlags);
 
                        list.Add(runtimeConstructorInfo);
                    }

                    return list; 
                }
 
                private unsafe List PopulateFields(Filter filter) 
                {
                    List list = new List(); 

                    RuntimeTypeHandle declaringTypeHandle = ReflectedTypeHandle;

                    #region Populate all static, instance and literal fields 
                    while(declaringTypeHandle.IsGenericVariable())
                        declaringTypeHandle = declaringTypeHandle.GetRuntimeType().BaseType.GetTypeHandleInternal(); 
 
                    while(!declaringTypeHandle.IsNullHandle())
                    { 
                        PopulateRtFields(filter, declaringTypeHandle, list);

                        PopulateLiteralFields(filter, declaringTypeHandle, list);
 
                        declaringTypeHandle = declaringTypeHandle.GetBaseTypeHandle();
                    } 
                    #endregion 

                    #region Populate Literal Fields on Interfaces 
                    if (ReflectedType.IsGenericParameter)
                    {
                        Type[] interfaces = ReflectedTypeHandle.GetRuntimeType().BaseType.GetInterfaces();
 
                        for (int i = 0; i < interfaces.Length; i++)
                        { 
                            // Populate literal fields defined on any of the interfaces implemented by the declaring type 
                            PopulateLiteralFields(filter, interfaces[i].GetTypeHandleInternal(), list);
                            PopulateRtFields(filter, interfaces[i].GetTypeHandleInternal(), list); 
                        }
                    }
                    else
                    { 
                        RuntimeTypeHandle[] interfaces = ReflectedTypeHandle.GetInterfaces();
 
                        if (interfaces != null) 
                        {
                            for (int i = 0; i < interfaces.Length; i++) 
                            {
                                // Populate literal fields defined on any of the interfaces implemented by the declaring type
                                PopulateLiteralFields(filter, interfaces[i], list);
                                PopulateRtFields(filter, interfaces[i], list); 
                            }
                        } 
                    } 
                    #endregion
 
                    return list;
                }

                private unsafe void PopulateRtFields(Filter filter, RuntimeTypeHandle declaringTypeHandle, List list) 
                {
                    int** pResult = stackalloc int*[64]; 
                    int count = 64; 

                    if (!declaringTypeHandle.GetFields(pResult, &count)) 
                    {
                        fixed(int** pBigResult = new int*[count])
                        {
                            declaringTypeHandle.GetFields(pBigResult, &count); 
                            PopulateRtFields(filter, pBigResult, count, declaringTypeHandle, list);
                        } 
                    } 
                    else if (count > 0)
                    { 
                        PopulateRtFields(filter, pResult, count, declaringTypeHandle, list);
                    }
                }
 
                private unsafe void PopulateRtFields(Filter filter,
                    int** ppFieldHandles, int count, RuntimeTypeHandle declaringTypeHandle, List list) 
                { 
                    ASSERT.PRECONDITION(!declaringTypeHandle.IsNullHandle());
                    ASSERT.PRECONDITION(!ReflectedTypeHandle.IsNullHandle()); 

                    bool needsStaticFieldForGeneric = declaringTypeHandle.HasInstantiation() && !declaringTypeHandle.ContainsGenericVariables();
                    bool isInherited = !declaringTypeHandle.Equals(ReflectedTypeHandle);
 
                    for(int i = 0; i < count; i ++)
                    { 
                        RuntimeFieldHandle runtimeFieldHandle = new RuntimeFieldHandle(ppFieldHandles[i]); 

                        if (!filter.Match(runtimeFieldHandle.GetUtf8Name())) 
                            continue;

                        ASSERT.CONSISTENCY_CHECK(!runtimeFieldHandle.IsNullHandle());
 
                        FieldAttributes fieldAttributes = runtimeFieldHandle.GetAttributes();
                        FieldAttributes fieldAccess = fieldAttributes & FieldAttributes.FieldAccessMask; 
 
                        if (isInherited)
                        { 
                            if (fieldAccess == FieldAttributes.Private)
                                continue;
                        }
 
                        #region Calculate Binding Flags
                        bool isPublic = fieldAccess == FieldAttributes.Public; 
                        bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0; 
                        BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
                        #endregion 

                        // correct the FieldDesc if needed
                        if (needsStaticFieldForGeneric && isStatic)
                            runtimeFieldHandle = runtimeFieldHandle.GetStaticFieldForGenericType(declaringTypeHandle); 

                        RuntimeFieldInfo runtimeFieldInfo = 
                            new RtFieldInfo(runtimeFieldHandle, declaringTypeHandle.GetRuntimeType(), m_runtimeTypeCache, bindingFlags); 

                        list.Add(runtimeFieldInfo); 
                    }
                }

                private unsafe void PopulateLiteralFields(Filter filter, RuntimeTypeHandle declaringTypeHandle, List list) 
                {
                    ASSERT.PRECONDITION(!declaringTypeHandle.IsNullHandle()); 
                    ASSERT.PRECONDITION(!ReflectedTypeHandle.IsNullHandle()); 

                    int tkDeclaringType = declaringTypeHandle.GetToken(); 

                    // Our policy is that TypeDescs do not have metadata tokens
                    if (MdToken.IsNullToken(tkDeclaringType))
                        return; 

                    MetadataImport scope = declaringTypeHandle.GetModuleHandle().GetMetadataImport(); 
                    int cFields = scope.EnumFieldsCount(tkDeclaringType); 
                    int* tkFields = stackalloc int[cFields];
                    scope.EnumFields(tkDeclaringType, tkFields, cFields); 

                    for (int i = 0; i < cFields; i++)
                    {
                        int tkField = tkFields[i]; 
                        ASSERT.PRECONDITION(MdToken.IsTokenOfType(tkField, MetadataTokenType.FieldDef));
                        ASSERT.PRECONDITION(!MdToken.IsNullToken(tkField)); 
 
                        Utf8String name;
                        name = scope.GetName(tkField); 

                        if (!filter.Match(name))
                            continue;
 
                        FieldAttributes fieldAttributes;
                        scope.GetFieldDefProps(tkField, out fieldAttributes); 
 
                        FieldAttributes fieldAccess = fieldAttributes & FieldAttributes.FieldAccessMask;
 
                        if ((fieldAttributes & FieldAttributes.Literal) != 0)
                        {
                            bool isInherited = !declaringTypeHandle.Equals(ReflectedTypeHandle);
                            if (isInherited) 
                            {
                                bool isPrivate = fieldAccess == FieldAttributes.Private; 
                                if (isPrivate) 
                                    continue;
                            } 

                            #region Calculate Binding Flags
                            bool isPublic = fieldAccess == FieldAttributes.Public;
                            bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0; 
                            BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
                            #endregion 
 
                            RuntimeFieldInfo runtimeFieldInfo =
                            new MdFieldInfo(tkField, fieldAttributes, declaringTypeHandle, m_runtimeTypeCache, bindingFlags); 

                            list.Add(runtimeFieldInfo);
                        }
                    } 
                }
 
                private static void AddElementTypes(Type template, IList types) 
                {
                    if (!template.HasElementType) 
                        return;

                    AddElementTypes(template.GetElementType(), types);
 
                    for (int i = 0; i < types.Count; i ++)
                    { 
                        if (template.IsArray) 
                        {
                            if (template.IsSzArray) 
                                types[i] = types[i].MakeArrayType();
                            else
                                types[i] = types[i].MakeArrayType(template.GetArrayRank());
                        } 
                        else if (template.IsPointer)
                        { 
                            types[i] = types[i].MakePointerType(); 
                        }
                    } 
                }

                private List PopulateInterfaces(Filter filter)
                { 
                    List list = new List();
 
                    RuntimeTypeHandle declaringTypeHandle = ReflectedTypeHandle; 

                    if (!declaringTypeHandle.IsGenericVariable()) 
                    {
                        RuntimeTypeHandle[] ifaces = ReflectedTypeHandle.GetInterfaces();

                        if (ifaces != null) 
                        {
                            for (int i = 0; i < ifaces.Length; i++) 
                            { 
                                RuntimeType interfaceType = ifaces[i].GetRuntimeType();
 
                                if (!filter.Match(interfaceType.GetTypeHandleInternal().GetUtf8Name()))
                                    continue;

                                ASSERT.CONSISTENCY_CHECK(interfaceType.IsInterface); 
                                list.Add(interfaceType);
                            } 
                        } 

                        if (ReflectedType.IsSzArray) 
                        {
                            Type arrayType = ReflectedType.GetElementType();

                            if (!arrayType.IsPointer) 
                            {
                                Type iList = typeof(IList<>).MakeGenericType(arrayType); 
 
                                if (iList.IsAssignableFrom(ReflectedType))
                                { 
                                    if (filter.Match(iList.GetTypeHandleInternal().GetUtf8Name()))
                                        list.Add(iList as RuntimeType);

                                    Type[] iFaces = iList.GetInterfaces(); 
                                    for(int j = 0; j < iFaces.Length; j++)
                                    { 
                                        Type iFace = iFaces[j]; 
                                        if (iFace.IsGenericType && filter.Match(iFace.GetTypeHandleInternal().GetUtf8Name()))
                                            list.Add(iFaces[j] as RuntimeType); 
                                    }
                                }
                            }
                        } 
                    }
                    else 
                    { 
                        List al = new List();
 
                        // Get all constraints
                        Type[] constraints = declaringTypeHandle.GetRuntimeType().GetGenericParameterConstraints();

                        // Populate transitive closure of all interfaces in constraint set 
                        for (int i = 0; i < constraints.Length; i++)
                        { 
                            Type constraint = constraints[i]; 
                            if (constraint.IsInterface)
                                al.Add(constraint as RuntimeType); 

                            Type[] temp = constraint.GetInterfaces();
                            for (int j = 0; j < temp.Length; j++)
                                al.Add(temp[j] as RuntimeType); 
                        }
 
                        // Remove duplicates 
                        Hashtable ht = new Hashtable();
                        for (int i = 0; i < al.Count; i++) 
                        {
                            Type constraint = al[i] as Type;
                            if (!ht.Contains(constraint))
                                ht[constraint] = constraint; 
                        }
 
                        Type[] interfaces = new Type[ht.Values.Count]; 
                        ht.Values.CopyTo(interfaces, 0);
 
                        // Populate link-list
                        for (int i = 0; i < interfaces.Length; i++)
                        {
                            if (!filter.Match(interfaces[i].GetTypeHandleInternal().GetUtf8Name())) 
                                continue;
 
                            list.Add(interfaces[i] as RuntimeType); 
                        }
                    } 

                    return list;
                }
 
                private unsafe List PopulateNestedClasses(Filter filter)
                { 
                    List list = new List(); 

                    RuntimeTypeHandle declaringTypeHandle = ReflectedTypeHandle; 

                    if (declaringTypeHandle.IsGenericVariable())
                    {
                        while(declaringTypeHandle.IsGenericVariable()) 
                            declaringTypeHandle = declaringTypeHandle.GetRuntimeType().BaseType.GetTypeHandleInternal();
                    } 
 
                    int tkEnclosingType = declaringTypeHandle.GetToken();
 
                    // For example, TypeDescs do not have metadata tokens
                    if (MdToken.IsNullToken(tkEnclosingType))
                        return list;
 
                    ModuleHandle moduleHandle = declaringTypeHandle.GetModuleHandle();
                    MetadataImport scope = moduleHandle.GetMetadataImport(); 
 
                    int cNestedClasses = scope.EnumNestedTypesCount(tkEnclosingType);
                    int* tkNestedClasses = stackalloc int[cNestedClasses]; 
                    scope.EnumNestedTypes(tkEnclosingType, tkNestedClasses, cNestedClasses);

                    for (int i = 0; i < cNestedClasses; i++)
                    { 
                        RuntimeTypeHandle nestedTypeHandle = new RuntimeTypeHandle();
 
                        try 
                        {
                            nestedTypeHandle = moduleHandle.ResolveTypeHandle(tkNestedClasses[i]); 
                        }
                        catch(System.TypeLoadException)
                        {
                            // In a reflection emit scenario, we may have a token for a class which 
                            // has not been baked and hence cannot be loaded.
                            continue; 
                        } 

                        if (!filter.Match(nestedTypeHandle.GetRuntimeType().GetTypeHandleInternal().GetUtf8Name())) 
                            continue;

                        list.Add(nestedTypeHandle.GetRuntimeType());
                    } 

                    return list; 
                } 

                private unsafe List PopulateEvents(Filter filter) 
                {
                    ASSERT.PRECONDITION(!ReflectedTypeHandle.IsNullHandle());

                    Hashtable csEventInfos = new Hashtable(); 

                    RuntimeTypeHandle declaringTypeHandle = ReflectedTypeHandle; 
                    List list = new List(); 

                    bool isInterface = (declaringTypeHandle.GetAttributes() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface; 

                    if (!isInterface)
                    {
                        while(declaringTypeHandle.IsGenericVariable()) 
                            declaringTypeHandle = declaringTypeHandle.GetRuntimeType().BaseType.GetTypeHandleInternal();
 
                        // Populate associates off of the class hierarchy 
                        while(!declaringTypeHandle.IsNullHandle())
                        { 
                            PopulateEvents(filter, declaringTypeHandle, csEventInfos, list);
                            declaringTypeHandle = declaringTypeHandle.GetBaseTypeHandle();
                        }
                    } 
                    else
                    { 
                        // Populate associates for this interface 
                        PopulateEvents(filter, declaringTypeHandle, csEventInfos, list);
                    } 

                    return list;
                }
 
                private unsafe void PopulateEvents(
                    Filter filter, RuntimeTypeHandle declaringTypeHandle, Hashtable csEventInfos, List list) 
                { 
                    int tkDeclaringType = declaringTypeHandle.GetToken();
 
                    // Arrays, Pointers, ByRef types and others generated only the fly by the RT do not have tokens.
                    if (MdToken.IsNullToken(tkDeclaringType))
                        return;
 
                    MetadataImport scope = declaringTypeHandle.GetModuleHandle().GetMetadataImport();
                    int cEvents = scope.EnumEventsCount(tkDeclaringType); 
                    int* tkEvents = stackalloc int[cEvents]; 
                    scope.EnumEvents(tkDeclaringType, tkEvents, cEvents);
                    PopulateEvents(filter, declaringTypeHandle, scope, tkEvents, cEvents, csEventInfos, list); 
                }

                private unsafe void PopulateEvents(Filter filter,
                    RuntimeTypeHandle declaringTypeHandle, MetadataImport scope, int* tkAssociates, int cAssociates, Hashtable csEventInfos, List list) 
                {
                    for (int i = 0; i < cAssociates; i++) 
                    { 
                        int tkAssociate = tkAssociates[i];
                        bool isPrivate; 

                        ASSERT.PRECONDITION(!MdToken.IsNullToken(tkAssociate));
                        ASSERT.PRECONDITION(MdToken.IsTokenOfType(tkAssociate, MetadataTokenType.Event));
 
                        Utf8String name;
                        name = scope.GetName(tkAssociate); 
 
                        if (!filter.Match(name))
                            continue; 

                        RuntimeEventInfo eventInfo = new RuntimeEventInfo(
                            tkAssociate, declaringTypeHandle.GetRuntimeType() as RuntimeType, m_runtimeTypeCache, out isPrivate);
 
                        #region Remove Inherited Privates
                        if (!declaringTypeHandle.Equals(m_runtimeTypeCache.RuntimeTypeHandle) && isPrivate) 
                            continue; 
                        #endregion
 
                        #region Remove Duplicates
                        if (csEventInfos[eventInfo.Name] != null)
                            continue;
 
                        csEventInfos[eventInfo.Name] = eventInfo;
                        #endregion 
 
                        list.Add(eventInfo);
                    } 
                }

                private unsafe List PopulateProperties(Filter filter)
                { 
                    ASSERT.PRECONDITION(!ReflectedTypeHandle.IsNullHandle());
                    ASSERT.CONSISTENCY_CHECK(m_csMemberInfos == null); 
 
                    Hashtable csPropertyInfos = new Hashtable();
 
                    RuntimeTypeHandle declaringTypeHandle = ReflectedTypeHandle;
                    List list = new List();

                    bool isInterface = (declaringTypeHandle.GetAttributes() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface; 

                    if (!isInterface) 
                    { 
                        while(declaringTypeHandle.IsGenericVariable())
                            declaringTypeHandle = declaringTypeHandle.GetRuntimeType().BaseType.GetTypeHandleInternal(); 

                        // Populate associates off of the class hierarchy
                        while(!declaringTypeHandle.IsNullHandle())
                        { 
                            PopulateProperties(filter, declaringTypeHandle, csPropertyInfos, list);
                            declaringTypeHandle = declaringTypeHandle.GetBaseTypeHandle(); 
                        } 
                    }
                    else 
                    {
                        // Populate associates for this interface
                        PopulateProperties(filter, declaringTypeHandle, csPropertyInfos, list);
                    } 

                    return list; 
                } 

                private unsafe void PopulateProperties(Filter filter, 
                    RuntimeTypeHandle declaringTypeHandle, Hashtable csPropertyInfos, List list)
                {
                    int tkDeclaringType = declaringTypeHandle.GetToken();
 
                    // Arrays, Pointers, ByRef types and others generated only the fly by the RT do not have tokens.
                    if (MdToken.IsNullToken(tkDeclaringType)) 
                        return; 

                    MetadataImport scope = declaringTypeHandle.GetModuleHandle().GetMetadataImport(); 
                    int cProperties = scope.EnumPropertiesCount(tkDeclaringType);
                    int* tkProperties = stackalloc int[cProperties];
                    scope.EnumProperties(tkDeclaringType, tkProperties, cProperties);
                    PopulateProperties(filter, declaringTypeHandle, tkProperties, cProperties, csPropertyInfos, list); 
                }
 
                private unsafe void PopulateProperties(Filter filter, 
                    RuntimeTypeHandle declaringTypeHandle, int* tkAssociates, int cProperties, Hashtable csPropertyInfos, List list)
                { 
                    for(int i = 0; i < cProperties; i ++)
                    {
                        int tkAssociate = tkAssociates[i];
                        bool isPrivate; 

                        ASSERT.PRECONDITION(!MdToken.IsNullToken(tkAssociate)); 
                        ASSERT.PRECONDITION(MdToken.IsTokenOfType(tkAssociate, MetadataTokenType.Property)); 

                        Utf8String name; 
                        name = declaringTypeHandle.GetRuntimeType().Module.MetadataImport.GetName(tkAssociate);

                        if (!filter.Match(name))
                            continue; 

                        RuntimePropertyInfo propertyInfo = 
                            new RuntimePropertyInfo( 
                            tkAssociate, declaringTypeHandle.GetRuntimeType() as RuntimeType, m_runtimeTypeCache, out isPrivate);
 
                        #region Remove Privates
                        if (!declaringTypeHandle.Equals(m_runtimeTypeCache.RuntimeTypeHandle) && isPrivate)
                            continue;
                        #endregion 

                        #region Remove Duplicates 
                        List cache = csPropertyInfos[propertyInfo.Name] as List; 

                        if (cache == null) 
                        {
                            cache = new List();
                            csPropertyInfos[propertyInfo.Name] = cache;
                        } 
                        else
                        { 
                            for (int j = 0; j < cache.Count; j ++) 
                            {
                                if (propertyInfo.EqualsSig(cache[j])) 
                                {
                                    cache = null;
                                    break;
                                } 
                            }
                        } 
 
                        if (cache == null)
                            continue; 

                        cache.Add(propertyInfo);
                        #endregion
 
                        list.Add(propertyInfo);
                    } 
                } 
                #endregion
 
                #region NonPrivate Members
                internal CerArrayList GetMemberList(MemberListType listType, string name, CacheType cacheType)
                {
                    CerArrayList list = null; 

                    switch(listType) 
                    { 
                        case MemberListType.CaseSensitive:
                            if (m_csMemberInfos == null) 
                            {
                                return Populate(name, listType, cacheType);
                            }
                            else 
                            {
                                list = m_csMemberInfos[name]; 
 
                                if (list == null)
                                    return Populate(name, listType, cacheType); 

                                return list;
                            }
 
                        case MemberListType.All:
                            if (m_cacheComplete) 
                                return m_root; 

                            return Populate(null, listType, cacheType); 

                        default:
                            if (m_cisMemberInfos == null)
                            { 
                                return Populate(name, listType, cacheType);
                            } 
                            else 
                            {
                                list = m_cisMemberInfos[name]; 

                                if (list == null)
                                    return Populate(name, listType, cacheType);
 
                                return list;
                            } 
                    } 
                }
 
                internal RuntimeTypeHandle ReflectedTypeHandle
                {
                    get
                    { 
                        return m_runtimeTypeCache.RuntimeTypeHandle;
                    } 
                } 
                internal RuntimeType ReflectedType
                { 
                    get
                    {
                        return ReflectedTypeHandle.GetRuntimeType();
                    } 
                }
                #endregion 
            } 
            #endregion
 
            #region Private Data Members
            private WhatsCached m_whatsCached;
            private RuntimeTypeHandle m_runtimeTypeHandle;
            private RuntimeType m_runtimeType; 
            private RuntimeType m_enclosingType;
            private TypeCode m_typeCode; 
            private string m_name, m_fullname, m_toString, m_namespace; 
            private bool m_isGlobal;
            private bool m_bIsDomainInitialized; 
            private MemberInfoCache m_methodInfoCache;
            private MemberInfoCache m_constructorInfoCache;
            private MemberInfoCache m_fieldInfoCache;
            private MemberInfoCache m_interfaceCache; 
            private MemberInfoCache m_nestedClassesCache;
            private MemberInfoCache m_propertyInfoCache; 
            private MemberInfoCache m_eventInfoCache; 
            private static CerHashtable s_methodInstantiations;
            private static bool s_dontrunhack = false; 
            #endregion

            #region Constructor
            internal RuntimeTypeCache(RuntimeType runtimeType) 
            {
                m_typeCode = TypeCode.Empty; 
                m_runtimeType = runtimeType; 
                m_runtimeTypeHandle = runtimeType.GetTypeHandleInternal();
                m_isGlobal = m_runtimeTypeHandle.GetModuleHandle().GetModuleTypeHandle().Equals(m_runtimeTypeHandle); 
                s_dontrunhack = true;
                Prejitinit_HACK();
            }
            #endregion 

            #region Private Members 
            private string ConstructName(ref string name, bool nameSpace, bool fullinst, bool assembly) 
            {
                if (name == null) 
                {
                    name = RuntimeTypeHandle.ConstructName(nameSpace, fullinst, assembly);
                }
                return name; 
            }
 
            private CerArrayList GetMemberList(ref MemberInfoCache m_cache, MemberListType listType, string name, CacheType cacheType) 
                where T : MemberInfo
            { 
                MemberInfoCache existingCache = GetMemberCache(ref m_cache);
                return existingCache.GetMemberList(listType, name, cacheType);
            }
 
            private MemberInfoCache GetMemberCache(ref MemberInfoCache m_cache)
                where T : MemberInfo 
            { 
                MemberInfoCache existingCache = m_cache;
 
                if (existingCache == null)
                {
                    MemberInfoCache newCache = new MemberInfoCache(this);
                    existingCache = Interlocked.CompareExchange(ref m_cache, newCache, null); 
                    if (existingCache == null)
                        existingCache = newCache; 
                } 

                return existingCache; 
            }
            #endregion

            #region Internal Members 
            internal bool DomainInitialized
            { 
                get { return m_bIsDomainInitialized; } 
                set { m_bIsDomainInitialized = value; }
            } 

            internal string GetName()
            {
                return ConstructName(ref m_name, false, false, false); 
            }
 
            internal unsafe string GetNameSpace() 
            {
                // @Optimization - Use ConstructName to populate m_namespace 
                if (m_namespace == null)
                {
                    Type type = m_runtimeType;
                    type = type.GetRootElementType(); 

                    while (type.IsNested) 
                        type = type.DeclaringType; 

                    m_namespace = type.GetTypeHandleInternal().GetModuleHandle( 
                        ).GetMetadataImport().GetNamespace(type.MetadataToken).ToString();
                }

                return m_namespace; 
            }
 
            internal string GetToString() 
            {
                return ConstructName(ref m_toString, true, false, false); 
            }

            internal string GetFullName()
            { 
                if (!m_runtimeType.IsGenericTypeDefinition && m_runtimeType.ContainsGenericParameters)
                    return null; 
 
                return ConstructName(ref m_fullname, true, true, false);
            } 

            internal TypeCode TypeCode
            {
                get { return m_typeCode; } 
                set { m_typeCode = value; }
            } 
 
            internal unsafe RuntimeType GetEnclosingType()
            { 
                if ((m_whatsCached & WhatsCached.EnclosingType) == 0)
                {
                    m_enclosingType = RuntimeTypeHandle.GetDeclaringType().GetRuntimeType();
 
                    m_whatsCached |= WhatsCached.EnclosingType;
                } 
 
                return m_enclosingType;
            } 

            internal bool IsGlobal
            {
                [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
                get { return m_isGlobal; }
            } 
            internal RuntimeType RuntimeType { get { return m_runtimeType; } } 
            internal RuntimeTypeHandle RuntimeTypeHandle
            { 
                get
                {
                    return m_runtimeTypeHandle;
                } 
            }
            internal void InvalidateCachedNestedType() 
            { 
                m_nestedClassesCache = null;
            } 
            #endregion

            #region Caches Accessors
            internal MethodInfo GetGenericMethodInfo(RuntimeMethodHandle genericMethod) 
            {
                if (s_methodInstantiations == null) 
                    Interlocked.CompareExchange(ref s_methodInstantiations, new CerHashtable(), null); 

                RuntimeMethodInfo rmi = new RuntimeMethodInfo( 
                    genericMethod, genericMethod.GetDeclaringType(), this,
                    genericMethod.GetAttributes(), (BindingFlags)(-1));

                RuntimeMethodInfo crmi = null; 

                crmi = s_methodInstantiations[rmi]; 
                if (crmi != null) 
                    return crmi;
 
                bool lockTaken = false;
                bool preallocationComplete = false;
                RuntimeHelpers.PrepareConstrainedRegions();
                try 
                {
                    Monitor.ReliableEnter(s_methodInstantiations, ref lockTaken); 
 
                    crmi = s_methodInstantiations[rmi];
                    if (crmi != null) 
                        return crmi;

                    s_methodInstantiations.Preallocate(1);
 
                    preallocationComplete = true;
                } 
                finally 
                {
                    if (preallocationComplete) 
                    {
                        s_methodInstantiations[rmi] = rmi;
                    }
 
                    if (lockTaken)
                    { 
                        Monitor.Exit(s_methodInstantiations); 
                    }
                } 

                return rmi;
            }
 
            internal CerArrayList GetMethodList(MemberListType listType, string name)
            { 
                return GetMemberList(ref m_methodInfoCache, listType, name, CacheType.Method); 
            }
 
            internal CerArrayList GetConstructorList(MemberListType listType, string name)
            {
                return GetMemberList(ref m_constructorInfoCache, listType, name, CacheType.Constructor);
            } 

            internal CerArrayList GetPropertyList(MemberListType listType, string name) 
            { 
                return GetMemberList(ref m_propertyInfoCache, listType, name, CacheType.Property);
            } 

            internal CerArrayList GetEventList(MemberListType listType, string name)
            {
                return GetMemberList(ref m_eventInfoCache, listType, name, CacheType.Event); 
            }
 
            internal CerArrayList GetFieldList(MemberListType listType, string name) 
            {
                return GetMemberList(ref m_fieldInfoCache, listType, name, CacheType.Field); 
            }

            internal CerArrayList GetInterfaceList(MemberListType listType, string name)
            { 
                return GetMemberList(ref m_interfaceCache, listType, name, CacheType.Interface);
            } 
 
            internal CerArrayList GetNestedTypeList(MemberListType listType, string name)
            { 
                return GetMemberList(ref m_nestedClassesCache, listType, name, CacheType.NestedType);
            }

            internal MethodBase GetMethod(RuntimeTypeHandle declaringType, RuntimeMethodHandle method) 
            {
                GetMemberCache(ref m_methodInfoCache); 
                return m_methodInfoCache.AddMethod(declaringType, method, CacheType.Method); 
            }
 
            internal MethodBase GetConstructor(RuntimeTypeHandle declaringType, RuntimeMethodHandle constructor)
            {
                GetMemberCache(ref m_constructorInfoCache);
                return m_constructorInfoCache.AddMethod(declaringType, constructor, CacheType.Constructor); 
            }
 
            internal FieldInfo GetField(RuntimeFieldHandle field) 
            {
                GetMemberCache(ref m_fieldInfoCache); 
                return m_fieldInfoCache.AddField(field);
            }

            #endregion 
        }
        #endregion 
 
        #region Static Members
 
        #region Internal
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        static internal extern void PrepareMemberInfoCache(RuntimeTypeHandle rt);
 
        internal static MethodBase GetMethodBase(ModuleHandle scope, int typeMetadataToken)
        { 
            return GetMethodBase(scope.ResolveMethodHandle(typeMetadataToken)); 
        }
 
        internal static MethodBase GetMethodBase(Module scope, int typeMetadataToken)
        {
            return GetMethodBase(scope.GetModuleHandle(), typeMetadataToken);
        } 

        internal static MethodBase GetMethodBase(RuntimeMethodHandle methodHandle) 
        { 
            return GetMethodBase(RuntimeTypeHandle.EmptyHandle, methodHandle);
        } 

        internal unsafe static MethodBase GetMethodBase(RuntimeTypeHandle reflectedTypeHandle, RuntimeMethodHandle methodHandle)
        {
            ASSERT.CONSISTENCY_CHECK(!reflectedTypeHandle.IsNullHandle()); 
            ASSERT.CONSISTENCY_CHECK(!methodHandle.IsNullHandle());
 
            if (methodHandle.IsDynamicMethod()) 
            {
                Resolver resolver = methodHandle.GetResolver(); 

                if (resolver != null)
                    return resolver.GetDynamicMethod();
 
                return null;
            } 
 
            // verify the type/method relationship
            Type declaredType = methodHandle.GetDeclaringType().GetRuntimeType(); 
            RuntimeType reflectedType = reflectedTypeHandle.GetRuntimeType();

            RuntimeTypeHandle[] methodInstantiation = null;
            bool fNeedInstantiatingStub = false; 

            if (reflectedType == null) 
                reflectedType = declaredType as RuntimeType; 

            if (reflectedType.IsArray) 
            {
                MethodBase[] methodBases = reflectedType.GetMember(
                    methodHandle.GetName(), MemberTypes.Constructor | MemberTypes.Method,
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) as MethodBase[]; 

                bool loaderAssuredCompatible = false; 
                for (int i = 0; i < methodBases.Length; i ++) 
                {
                    if (methodBases[i].GetMethodHandle() == methodHandle) 
                        loaderAssuredCompatible = true;
                }

                if (!loaderAssuredCompatible) 
                    throw new ArgumentException(String.Format(
                        CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"), 
                        reflectedType.ToString(), declaredType.ToString())); 

                declaredType = reflectedType; 
            }
            else if (!declaredType.IsAssignableFrom(reflectedType))
            {
                if (!declaredType.IsGenericType) 
                    throw new ArgumentException(String.Format(
                        CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"), 
                        reflectedType.ToString(), declaredType.ToString())); 

                // ignoring instantiation is the ReflectedType a subtype of the DeclaringType 
                Type declaringDefinition = declaredType.GetGenericTypeDefinition();

                Type baseType = reflectedType;
 
                while (baseType != null)
                { 
                    Type baseDefinition = baseType; 

                    if (baseDefinition.IsGenericType && !baseType.IsGenericTypeDefinition) 
                        baseDefinition = baseDefinition.GetGenericTypeDefinition();

                    if (baseDefinition.Equals(declaringDefinition))
                        break; 

                    baseType = baseType.BaseType; 
                } 

                if (baseType == null) 
                {
                    // ignoring instantiation is the ReflectedType is not a subtype of the DeclaringType
                    throw new ArgumentException(String.Format(
                        CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"), 
                        reflectedType.ToString(), declaredType.ToString()));
                } 
 
                // remap the method to same method on the subclass ReflectedType
                declaredType = baseType; 

                methodInstantiation = methodHandle.GetMethodInstantiation();

                bool bIsGenericMethodDefinition = methodHandle.IsGenericMethodDefinition(); 

                // lookup via v-table slot the RuntimeMethodHandle on the new declaring type 
                methodHandle = methodHandle.GetMethodFromCanonical(declaredType.GetTypeHandleInternal()); 

                // if the original methodHandle was the definition then we don't need to rebind generic method arguments 
                // because all RuntimeMethodHandles retrieved off of the canonical method table are definitions. That's
                // why for everything else we need to rebind the generic method arguments.
                if (!bIsGenericMethodDefinition)
                { 
                    fNeedInstantiatingStub = true;
                } 
            } 

            if (declaredType.IsValueType) 
                methodHandle = methodHandle.GetUnboxingStub();

            if ( fNeedInstantiatingStub ||
                 ( declaredType.GetTypeHandleInternal().HasInstantiation() && 
                   !declaredType.GetTypeHandleInternal().IsGenericTypeDefinition() &&
                   !methodHandle.HasMethodInstantiation())) 
            { 
                // if declaredType is an instantiated type and methodHandle is not generic get the instantiated MethodDesc (if needed)
                // MemberInfoCache.PopulateMethods and MemberInfoCache.PopulateConstructors do this already 
                methodHandle = methodHandle.GetInstantiatingStub(declaredType.GetTypeHandleInternal(), methodInstantiation);
            }

            if (methodHandle.IsConstructor()) 
            {
                // Constructor case: constructors cannot be generic 
                return reflectedType.Cache.GetConstructor(declaredType.GetTypeHandleInternal(), methodHandle); 
            }
            else 
            {
                // Method case
                if (methodHandle.HasMethodInstantiation() && !methodHandle.IsGenericMethodDefinition())
                    return reflectedType.Cache.GetGenericMethodInfo(methodHandle); 
                else
                    return reflectedType.Cache.GetMethod(declaredType.GetTypeHandleInternal(), methodHandle); 
            } 
        }
 
        internal bool DomainInitialized
        {
            get { return Cache.DomainInitialized; }
            set { Cache.DomainInitialized = value; } 
        }
 
        internal unsafe static FieldInfo GetFieldInfo(RuntimeFieldHandle fieldHandle) 
        {
            return GetFieldInfo(fieldHandle.GetApproxDeclaringType(), fieldHandle); 
        }

        internal unsafe static FieldInfo GetFieldInfo(RuntimeTypeHandle reflectedTypeHandle, RuntimeFieldHandle fieldHandle)
        { 
            // verify the type/method relationship
            if (reflectedTypeHandle.IsNullHandle()) 
            { 
                reflectedTypeHandle = fieldHandle.GetApproxDeclaringType();
            } 
            else
            {
                RuntimeTypeHandle declaredTypeHandle = fieldHandle.GetApproxDeclaringType();
                if (!reflectedTypeHandle.Equals(declaredTypeHandle)) 
                {
                    if (!fieldHandle.AcquiresContextFromThis() || 
                        !declaredTypeHandle.GetCanonicalHandle().Equals(reflectedTypeHandle.GetCanonicalHandle())) 
                    {
                        throw new ArgumentException(String.Format( 
                            CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveFieldHandle"),
                            reflectedTypeHandle.GetRuntimeType().ToString(),
                            declaredTypeHandle.GetRuntimeType().ToString()));
                    } 
                }
            } 
 
            return reflectedTypeHandle.GetRuntimeType().Cache.GetField(fieldHandle);
        } 

        // Called internally
        internal unsafe static PropertyInfo GetPropertyInfo(RuntimeTypeHandle reflectedTypeHandle, int tkProperty)
        { 
            RuntimePropertyInfo property = null;
            CerArrayList candidates = 
                reflectedTypeHandle.GetRuntimeType().Cache.GetPropertyList(MemberListType.All, null); 

            for (int i = 0; i < candidates.Count; i++) 
            {
                property = candidates[i];
                if (property.MetadataToken == tkProperty)
                    return property; 
            }
 
            ASSERT.UNREACHABLE(); 
            throw new SystemException();
        } 

        private static void ThrowIfTypeNeverValidGenericArgument(Type type)
        {
            if (type.IsPointer || type.IsByRef || type == typeof(void)) 
                throw new ArgumentException(
                    String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_NeverValidGenericArgument"), type.ToString())); 
        } 

 
        internal static void SanityCheckGenericArguments(Type[] genericArguments, Type[] 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( 
                    String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_NotEnoughGenArguments", genericArguments.Length, genericParamters.Length))); 
        }
 
        internal static void ValidateGenericArguments(MemberInfo definition, Type[] genericArguments, Exception e)
        {
            RuntimeTypeHandle[] typeContextHandle = null;
            RuntimeTypeHandle[] methodContextHandle = null; 
            Type[] genericParamters = null;
 
            if (definition is Type) 
            {
                Type genericTypeDefinition = (Type)definition; 
                genericParamters = genericTypeDefinition.GetGenericArguments();
                typeContextHandle = new RuntimeTypeHandle[genericArguments.Length];
                for (int i = 0; i < genericArguments.Length; i ++)
                    typeContextHandle[i] = genericArguments[i].GetTypeHandleInternal(); 
            }
            else 
            { 
                MethodInfo genericMethodDefinition = (MethodInfo)definition;
                genericParamters = genericMethodDefinition.GetGenericArguments(); 
                methodContextHandle = new RuntimeTypeHandle[genericArguments.Length];
                for (int i = 0; i < genericArguments.Length; i ++)
                    methodContextHandle[i] = genericArguments[i].GetTypeHandleInternal();
 
                Type declaringType = genericMethodDefinition.DeclaringType;
                if (declaringType != null) 
                    typeContextHandle = declaringType.GetTypeHandleInternal().GetInstantiation(); 
            }
 
            for (int i = 0; i < genericArguments.Length; i++)
            {
                Type genericArgument = genericArguments[i];
                Type genericParameter = genericParamters[i]; 

                if (!genericParameter.GetTypeHandleInternal().SatisfiesConstraints( 
                    typeContextHandle, methodContextHandle, genericArgument.GetTypeHandleInternal())) 
                {
                    throw new ArgumentException( 
                        String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_GenConstraintViolation"),
                        i.ToString(CultureInfo.CurrentCulture), genericArgument.ToString(), definition.ToString(), genericParameter.ToString()), e);
                }
            } 
        }
 
        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 = ""; 
                ASSERT.CONSISTENCY_CHECK(fullname.Equals(ns + "." + name)); 
            }
            else 
            {
                name = fullname;
            }
 
        }
        #endregion 
 
        #region Filters
        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;
        } 

        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))
                { 
                    name = name.Substring(0, name.Length - 1);
                    prefixLookup = true;
                    listType = MemberListType.All;
                } 
            }
            else 
            { 
                listType = MemberListType.All;
            } 
        }

        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); 
        } 

        private static bool FilterApplyPrefixLookup(MemberInfo memberInfo, string name, bool ignoreCase) 
        {
            ASSERT.CONSISTENCY_CHECK(name != null);

            if (ignoreCase) 
            {
                if (!memberInfo.Name.ToLower(CultureInfo.InvariantCulture).StartsWith(name, StringComparison.Ordinal)) 
                    return false; 
            }
            else 
            {
                if (!memberInfo.Name.StartsWith(name, StringComparison.Ordinal))
                    return false;
            } 

            return true; 
        } 

 
        private static bool FilterApplyBase(
            MemberInfo memberInfo, BindingFlags bindingFlags, bool isPublic, bool isNonProtectedInternal, bool isStatic,
            string name, bool prefixLookup)
        { 
            #region Preconditions
            ASSERT.PRECONDITION(memberInfo != null); 
            ASSERT.PRECONDITION(name == null || (bindingFlags & BindingFlags.IgnoreCase) == 0 || (name.ToLower(CultureInfo.InvariantCulture).Equals(name))); 
            #endregion
 
            #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 = 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;
        } 


        private static bool FilterApplyType(
            Type type, BindingFlags bindingFlags, string name, bool prefixLookup, string ns) 
        {
            ASSERT.PRECONDITION(type != null); 
            ASSERT.PRECONDITION(type is RuntimeType); 

            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 && !type.Namespace.Equals(ns)) 
                return false; 

            return true; 
        }


        private static bool FilterApplyMethodBaseInfo( 
            MethodBase methodBase, BindingFlags bindingFlags, string name, CallingConventions callConv, Type[] argumentTypes,
            bool prefixLookup) 
        { 
            ASSERT.PRECONDITION(methodBase != null);
 
            #region Apply Base Filter
            bindingFlags ^= BindingFlags.DeclaredOnly;
            BindingFlags matchFlags;
 
            RuntimeMethodInfo methodInfo = methodBase as RuntimeMethodInfo;
            if (methodInfo == null) 
            { 
                RuntimeConstructorInfo constructorInfo = methodBase as RuntimeConstructorInfo;
                matchFlags = constructorInfo.BindingFlags; 
            }
            else
            {
                matchFlags = methodInfo.BindingFlags; 
            }
 
            if ((bindingFlags & matchFlags) != matchFlags || 
                (prefixLookup && !FilterApplyPrefixLookup(methodBase, name, (bindingFlags & BindingFlags.IgnoreCase) != 0)))
                return false; 
            #endregion

            return FilterApplyMethodBaseInfo(methodBase, bindingFlags, callConv, argumentTypes);
        } 

 
        private static bool FilterApplyMethodBaseInfo( 
            MethodBase methodBase, BindingFlags bindingFlags, CallingConventions callConv, Type[] argumentTypes)
        { 
            #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. 
                            ASSERT.CONSISTENCY_CHECK((callConv & CallingConventions.VarArgs) != 0); 
                        }
                        #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 (argumentTypes[i] != null && parameterInfos[i].ParameterType != argumentTypes[i]) 
                                    return false; 
                            }
                        } 
                    }
                    #endregion
                }
            } 
            #endregion
 
            return true; 
        }
 
        #endregion

        #endregion
 
        #region Private Data Members
        private IntPtr m_cache; 
        private RuntimeTypeHandle m_handle; 

        private class TypeCacheQueue 
        {
            // must be a power of 2 for this to work
            const int QUEUE_SIZE = 4;
 
            Object[] liveCache;
 
            internal TypeCacheQueue() 
            {
                liveCache = new Object[QUEUE_SIZE]; 
            }
        }
        private static TypeCacheQueue s_typeCache = null;
        #endregion 

        #region Constructor 
        private RuntimeType(RuntimeTypeHandle typeHandle) 
        {
            m_handle = typeHandle; 
        }

        internal RuntimeType() {}
        #endregion 

        #region Private\Internal Members 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
        internal override bool CacheEquals(object o)
        { 
            RuntimeType m = o as RuntimeType;

            if (m == null)
                return false; 

            return m.m_handle.Equals(m_handle); 
        } 

        private new RuntimeTypeCache Cache 
        {
            get
            {
                if (m_cache.IsNull()) 
                {
                    IntPtr newgcHandle = m_handle.GetGCHandle(GCHandleType.WeakTrackResurrection); 
                    IntPtr gcHandle = Interlocked.CompareExchange(ref m_cache, newgcHandle, (IntPtr)0); 
                    if (!gcHandle.IsNull())
                        m_handle.FreeGCHandle(newgcHandle); 
                }

                RuntimeTypeCache cache = GCHandle.InternalGet(m_cache) as RuntimeTypeCache;
                if (cache == null) 
                {
                    cache = new RuntimeTypeCache(this); 
                    RuntimeTypeCache existingCache = GCHandle.InternalCompareExchange(m_cache, cache, null, false) as RuntimeTypeCache; 
                    if (existingCache != null)
                        cache = existingCache; 
                    if (s_typeCache == null)
                        s_typeCache = new TypeCacheQueue();
                    //s_typeCache.Add(cache);
                } 
/*
                RuntimeTypeCache cache = m_cache as RuntimeTypeCache; 
                if (cache == null) 
                {
                    cache = new RuntimeTypeCache(TypeHandle); 
                    RuntimeTypeCache existingCache = Interlocked.CompareExchange(ref m_cache, cache, null) as RuntimeTypeCache;
                    if (existingCache != null)
                        cache = existingCache;
                } 
*/
                ASSERT.CONSISTENCY_CHECK(cache != null); 
                return cache; 
            }
        } 
        #endregion

        #region Type Overrides
 
        #region Get XXXInfo Candidates
        private MethodInfo[] GetMethodCandidates( 
            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);
 
            List candidates = new List();
            CerArrayList cache = Cache.GetMethodList(listType, name); 
 
            bindingAttr ^= BindingFlags.DeclaredOnly;
 
            for (int i = 0; i < cache.Count; i++)
            {
                RuntimeMethodInfo methodInfo = cache[i];
                if ((bindingAttr & methodInfo.BindingFlags) == methodInfo.BindingFlags && 
                    FilterApplyMethodBaseInfo(methodInfo, bindingAttr, callConv, types) &&
                    (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(methodInfo, name, ignoreCase))) 
                { 
                    candidates.Add(methodInfo);
                } 
            }

            return candidates.ToArray();
        } 

 
        private 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); 

            List candidates = new List(); 
            CerArrayList cache = Cache.GetConstructorList(listType, name); 

            bindingAttr ^= BindingFlags.DeclaredOnly; 

            for (int i = 0; i < cache.Count; i++)
            {
                RuntimeConstructorInfo constructorInfo = cache[i]; 
                if ((bindingAttr & constructorInfo.BindingFlags) == constructorInfo.BindingFlags &&
                    FilterApplyMethodBaseInfo(constructorInfo, bindingAttr, callConv, types) && 
                    (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(constructorInfo, name, ignoreCase))) 
                {
                    candidates.Add(constructorInfo); 
                }
            }

            return candidates.ToArray(); 
        }
 
 
        private 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); 

            List candidates = new List(); 
            CerArrayList cache = Cache.GetPropertyList(listType, name); 

            bindingAttr ^= BindingFlags.DeclaredOnly; 

            for (int i = 0; i < cache.Count; 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.ToArray(); 
        }
 
 
        private 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);
 
            List candidates = new List();
            CerArrayList cache = Cache.GetEventList(listType, name); 
 
            bindingAttr ^= BindingFlags.DeclaredOnly;
 
            for (int i = 0; i < cache.Count; i++)
            {
                RuntimeEventInfo eventInfo = cache[i];
                if ((bindingAttr & eventInfo.BindingFlags) == eventInfo.BindingFlags && 
                    (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(eventInfo, name, ignoreCase)))
                { 
                    candidates.Add(eventInfo); 
                }
            } 

            return candidates.ToArray();
        }
 
        private 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); 

            List candidates = new List();
            CerArrayList cache = Cache.GetFieldList(listType, name);
 
            bindingAttr ^= BindingFlags.DeclaredOnly;
 
            for (int i = 0; i < cache.Count; i++) 
            {
                RuntimeFieldInfo fieldInfo = cache[i]; 
                if ((bindingAttr & fieldInfo.BindingFlags) == fieldInfo.BindingFlags &&
                    (!prefixLookup || FilterApplyPrefixLookup(fieldInfo, name, ignoreCase)))
                {
                    candidates.Add(fieldInfo); 
                }
            } 
 
            return candidates.ToArray();
        } 

        private 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); 

            List candidates = new List();
            CerArrayList cache = Cache.GetNestedTypeList(listType, name);
 
            for (int i = 0; i < cache.Count; i++)
            { 
                RuntimeType nestedClass = cache[i]; 
                if (RuntimeType.FilterApplyType(nestedClass, bindingAttr, name, prefixLookup, ns))
                { 
                    candidates.Add(nestedClass);
                }
            }
 
            return candidates.ToArray();
        } 
        #endregion 

        #region Get All XXXInfos 
        public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
        {
            return GetMethodCandidates(null, bindingAttr, CallingConventions.Any, null, false);
        } 

[System.Runtime.InteropServices.ComVisible(true)] 
        public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) 
        {
            return GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, null, false); 
        }

        public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
        { 
            return GetPropertyCandidates(null, bindingAttr, null, false);
        } 
 
        public override EventInfo[] GetEvents(BindingFlags bindingAttr)
        { 
            return GetEventCandidates(null, bindingAttr, false);
        }

        public override FieldInfo[] GetFields(BindingFlags bindingAttr) 
        {
            return GetFieldCandidates(null, bindingAttr, false); 
        } 

        public override Type[] GetInterfaces() 
        {
              CerArrayList candidates = this.Cache.GetInterfaceList(MemberListType.All, null);
              Type[] interfaces = new Type[candidates.Count];
              for (int i = 0; i < candidates.Count; i++) 
                  JitHelpers.UnsafeSetArrayElement(interfaces, i, candidates[i]);
 
              return interfaces; 
        }
 
        public override Type[] GetNestedTypes(BindingFlags bindingAttr)
        {
            return GetNestedTypeCandidates(null, bindingAttr, false);
        } 

        public override MemberInfo[] GetMembers(BindingFlags bindingAttr) 
        { 
            MethodInfo[] methods = GetMethodCandidates(null, bindingAttr, CallingConventions.Any, null, false);
            ConstructorInfo[] constructors = GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, null, false); 
            PropertyInfo[] properties = GetPropertyCandidates(null, bindingAttr, null, false);
            EventInfo[] events = GetEventCandidates(null, bindingAttr, false);
            FieldInfo[] fields = GetFieldCandidates(null, bindingAttr, false);
            Type[] nestedTypes = GetNestedTypeCandidates(null, bindingAttr, false); 
            // Interfaces are excluded from the result of GetMembers
 
            MemberInfo[] members = new MemberInfo[ 
                methods.Length +
                constructors.Length + 
                properties.Length +
                events.Length +
                fields.Length +
                nestedTypes.Length]; 

            int i = 0; 
            Array.Copy(methods, 0, members, i, methods.Length); i += methods.Length; 
            Array.Copy(constructors, 0, members, i, constructors.Length); i += constructors.Length;
            Array.Copy(properties, 0, members, i, properties.Length); i += properties.Length; 
            Array.Copy(events, 0, members, i, events.Length); i += events.Length;
            Array.Copy(fields, 0, members, i, fields.Length); i += fields.Length;
            Array.Copy(nestedTypes, 0, members, i, nestedTypes.Length); i += nestedTypes.Length;
 
            ASSERT.POSTCONDITION(i == members.Length);
            return members; 
        } 

        public override InterfaceMapping GetInterfaceMap(Type ifaceType) 
        {
            if (IsGenericParameter)
                throw new InvalidOperationException(Environment.GetResourceString("Arg_GenericParameter"));
 
            if (ifaceType == null)
                throw new ArgumentNullException("ifaceType"); 
 
            if (!(ifaceType is RuntimeType))
                throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "ifaceType"); 

            RuntimeType ifaceRtType = ifaceType as RuntimeType;
            RuntimeTypeHandle ifaceRtTypeHandle = ifaceRtType.GetTypeHandleInternal();
 
            int firstIfaceSlot = GetTypeHandleInternal().GetFirstSlotForInterface(ifaceRtType.GetTypeHandleInternal());
            ASSERT.CONSISTENCY_CHECK(ifaceType.IsInterface);  // GetFirstSlotForInterface enforces this invariant 
            ASSERT.CONSISTENCY_CHECK(!IsInterface); // GetFirstSlotForInterface enforces this invariant 

            int ifaceSlotCount = ifaceRtTypeHandle.GetInterfaceMethodSlots(); 
            int ifaceStaticMethodCount = 0;

            // @Optimization - Most interface have the same number of static members.
 
            // Filter out static methods
            for (int i = 0; i < ifaceSlotCount; i ++) 
            { 
                if ((ifaceRtTypeHandle.GetMethodAt(i).GetAttributes() & MethodAttributes.Static) != 0)
                    ifaceStaticMethodCount++; 
            }

            int ifaceInstanceMethodCount = ifaceSlotCount - ifaceStaticMethodCount;
 
            InterfaceMapping im;
            im.InterfaceType = ifaceType; 
            im.TargetType = this; 
            im.InterfaceMethods = new MethodInfo[ifaceInstanceMethodCount];
            im.TargetMethods = new MethodInfo[ifaceInstanceMethodCount]; 

            for(int i = 0; i < ifaceSlotCount; i++)
            {
                RuntimeMethodHandle ifaceRtMethodHandle = ifaceRtTypeHandle.GetMethodAt(i); 
                if ((ifaceRtTypeHandle.GetMethodAt(i).GetAttributes() & MethodAttributes.Static) != 0)
                    continue; 
 
                bool mayNeedInstantiatingStub = ifaceRtTypeHandle.HasInstantiation() && !ifaceRtTypeHandle.IsGenericTypeDefinition();
 
                // if it is an instantiated type get the InstantiatedMethodDesc if needed
                if (mayNeedInstantiatingStub)
                    ifaceRtMethodHandle = ifaceRtMethodHandle.GetInstantiatingStubIfNeeded(ifaceRtTypeHandle);
 
                MethodBase ifaceMethodBase = RuntimeType.GetMethodBase(ifaceRtTypeHandle, ifaceRtMethodHandle);
                ASSERT.CONSISTENCY_CHECK(ifaceMethodBase is RuntimeMethodInfo); 
                im.InterfaceMethods[i] = (MethodInfo)ifaceMethodBase; 

                // If the slot is -1, then virtual stub dispatch is active. 
                // Should remove old "firstIfaceSlot + i" code when old behaviour disappears.
                int slot;
                if (firstIfaceSlot == -1)
                    slot = GetTypeHandleInternal().GetInterfaceMethodImplementationSlot(ifaceRtTypeHandle, ifaceRtMethodHandle); 
                else
                    slot = firstIfaceSlot + i; 
 
                if (slot == -1) continue;
 

                RuntimeTypeHandle classRtTypeHandle = GetTypeHandleInternal();
                RuntimeMethodHandle classRtMethodHandle = classRtTypeHandle.GetMethodAt(slot);
 
                mayNeedInstantiatingStub = classRtTypeHandle.HasInstantiation() && !classRtTypeHandle.IsGenericTypeDefinition();
 
                if (mayNeedInstantiatingStub) 
                    classRtMethodHandle = classRtMethodHandle.GetInstantiatingStubIfNeeded(classRtTypeHandle);
 
                MethodBase rtTypeMethodBase = RuntimeType.GetMethodBase(classRtTypeHandle, classRtMethodHandle);
                // a class may not implement all the methods of an interface (abstract class) so null is a valid value
                ASSERT.CONSISTENCY_CHECK(rtTypeMethodBase == null || rtTypeMethodBase is RuntimeMethodInfo);
                im.TargetMethods[i] = (MethodInfo)rtTypeMethodBase; 
            }
 
            return im; 
        }
        #endregion 

        #region Find XXXInfo
        protected override MethodInfo GetMethodImpl(
            String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConv, 
            Type[] types, ParameterModifier[] modifiers)
        { 
            MethodInfo[] candidates = GetMethodCandidates(name, bindingAttr, callConv, types, false); 

            if (candidates.Length == 0) 
                return null;

            if (types == null || types.Length == 0)
            { 
                if (candidates.Length == 1)
                { 
                    return candidates[0]; 
                }
                else if (types == null) 
                {
                    for (int j = 1; j < candidates.Length; j++)
                    {
                        MethodInfo methodInfo = candidates[j]; 
                        if (!System.DefaultBinder.CompareMethodSigAndName(methodInfo, candidates[0]))
                        { 
                            throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.Ambiguous")); 
                        }
                    } 

                    // All the methods have the exact same name and sig so return the most derived one.
                    return System.DefaultBinder.FindMostDerivedNewSlotMeth(candidates, candidates.Length) as MethodInfo;
                } 
            }
 
            if (binder == null) 
                binder = DefaultBinder;
 
            return binder.SelectMethod(bindingAttr, candidates, types, modifiers) as MethodInfo;
        }

 
        protected override ConstructorInfo GetConstructorImpl(
            BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, 
            Type[] types, ParameterModifier[] modifiers) 
        {
            ConstructorInfo[] candidates = GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, types, false); 

            if (binder == null)
                binder = DefaultBinder;
 
            if (candidates.Length == 0)
                return null; 
 
            if (types.Length == 0 && candidates.Length == 1)
            { 
                ParameterInfo[] parameters = (candidates[0]).GetParametersNoCopy();
                if (parameters == null || parameters.Length == 0)
                {
                    return candidates[0]; 
                }
            } 
 
            if ((bindingAttr & BindingFlags.ExactBinding) != 0)
                return System.DefaultBinder.ExactBinding(candidates, types, modifiers) as ConstructorInfo; 

            return binder.SelectMethod(bindingAttr, candidates, 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(); 

            PropertyInfo[] candidates = GetPropertyCandidates(name, bindingAttr, types, false);

            if (binder == null) 
                binder = DefaultBinder;
 
            if (candidates.Length == 0) 
                return null;
 
            if (types == null || types.Length == 0)
            {
                // no arguments
                if (candidates.Length == 1) 
                {
                    if (returnType != null && returnType != candidates[0].PropertyType) 
                        return null; 

                    return candidates[0]; 
                }
                else
                {
                    if (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(Environment.GetResourceString("RFLCT.Ambiguous")); 
                } 
            }
 
            if ((bindingAttr & BindingFlags.ExactBinding) != 0)
                return System.DefaultBinder.ExactPropertyBinding(candidates, returnType, types, modifiers);

            return binder.SelectProperty(bindingAttr, candidates, 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);
 
            CerArrayList cache = Cache.GetEventList(listType, name); 
            EventInfo match = null;
 
            bindingAttr ^= BindingFlags.DeclaredOnly;

            for (int i = 0; i < cache.Count; i++)
            { 
                RuntimeEventInfo eventInfo = cache[i];
                if ((bindingAttr & eventInfo.BindingFlags) == eventInfo.BindingFlags) 
                { 
                    if (match != null)
                        throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.Ambiguous")); 

                    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); 
 
            CerArrayList cache = Cache.GetFieldList(listType, name);
            FieldInfo match = null; 

            bindingAttr ^= BindingFlags.DeclaredOnly;
            bool multipleStaticFieldMatches = false;
 
            for (int i = 0; i < cache.Count; i++)
            { 
                RuntimeFieldInfo fieldInfo = cache[i]; 
                if ((bindingAttr & fieldInfo.BindingFlags) == fieldInfo.BindingFlags)
                { 
                    if (match != null)
                    {
                        if (fieldInfo.DeclaringType == match.DeclaringType)
                            throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.Ambiguous")); 

                        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(Environment.GetResourceString("RFLCT.Ambiguous")); 

            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);
 
            CerArrayList cache = Cache.GetInterfaceList(listType, name);

            RuntimeType match = null;
 
            for (int i = 0; i < cache.Count; i++)
            { 
                RuntimeType iface = cache[i]; 
                if (RuntimeType.FilterApplyType(iface, bindingAttr, name, false, ns))
                { 
                    if (match != null)
                        throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.Ambiguous"));

                    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);

            CerArrayList cache = Cache.GetNestedTypeList(listType, name); 

            RuntimeType match = null; 
 
            for (int i = 0; i < cache.Count; i++)
            { 
                RuntimeType nestedType = cache[i];
                if (RuntimeType.FilterApplyType(nestedType, bindingAttr, name, false, ns))
                {
                    if (match != null) 
                        throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.Ambiguous"));
 
                    match = nestedType; 
                }
            } 

            return match;
        }
 
        public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
        { 
            if (name == null) throw new ArgumentNullException(); 

            MethodInfo[] methods = new MethodInfo[0]; 
            ConstructorInfo[] constructors = new ConstructorInfo[0];
            PropertyInfo[] properties = new PropertyInfo[0];
            EventInfo[] events = new EventInfo[0];
            FieldInfo[] fields = new FieldInfo[0]; 
            Type[] nestedTypes = new Type[0];
 
            // Methods 
            if ((type & MemberTypes.Method) != 0)
                methods = GetMethodCandidates(name, bindingAttr, CallingConventions.Any, null, true); 

            // Constructors
            if ((type & MemberTypes.Constructor) != 0)
                constructors = GetConstructorCandidates(name, bindingAttr, CallingConventions.Any, null, true); 

            // Properties 
            if ((type & MemberTypes.Property) != 0) 
                properties = GetPropertyCandidates(name, bindingAttr, null, true);
 
            // Events
            if ((type & MemberTypes.Event) != 0)
                events = GetEventCandidates(name, bindingAttr, true);
 
            // Fields
            if ((type & MemberTypes.Field) != 0) 
                fields = GetFieldCandidates(name, bindingAttr, true); 

            // NestedTypes 
            if ((type & (MemberTypes.NestedType | MemberTypes.TypeInfo)) != 0)
                nestedTypes = GetNestedTypeCandidates(name, bindingAttr, true);

            switch(type) 
            {
                case MemberTypes.Method | MemberTypes.Constructor: 
                    MethodBase[] compressBaseses = new MethodBase[methods.Length + constructors.Length]; 
                    Array.Copy(methods, compressBaseses, methods.Length);
                    Array.Copy(constructors, 0, compressBaseses, methods.Length, constructors.Length); 
                    return compressBaseses;

                case MemberTypes.Method:
                    return methods; 

                case MemberTypes.Constructor: 
                    return constructors; 

                case MemberTypes.Field: 
                    return fields;

                case MemberTypes.Property:
                    return properties; 

                case MemberTypes.Event: 
                    return events; 

                case MemberTypes.NestedType: 
                    return nestedTypes;

                case MemberTypes.TypeInfo:
                    return nestedTypes; 
            }
 
            MemberInfo[] compressMembers = new MemberInfo[ 
                methods.Length +
                constructors.Length + 
                properties.Length +
                events.Length +
                fields.Length +
                nestedTypes.Length]; 

            int i = 0; 
            if (methods.Length > 0) Array.Copy(methods, 0, compressMembers, i, methods.Length); i += methods.Length; 
            if (constructors.Length > 0) Array.Copy(constructors, 0, compressMembers, i, constructors.Length); i += constructors.Length;
            if (properties.Length > 0) Array.Copy(properties, 0, compressMembers, i, properties.Length); i += properties.Length; 
            if (events.Length > 0) Array.Copy(events, 0, compressMembers, i, events.Length); i += events.Length;
            if (fields.Length > 0) Array.Copy(fields, 0, compressMembers, i, fields.Length); i += fields.Length;
            if (nestedTypes.Length > 0) Array.Copy(nestedTypes, 0, compressMembers, i, nestedTypes.Length); i += nestedTypes.Length;
 
            ASSERT.POSTCONDITION(i == compressMembers.Length);
            return compressMembers; 
        } 
        #endregion
 
        #region Identity
        public override Module Module
        {
            get 
            {
                return GetTypeHandleInternal().GetModuleHandle().GetModule(); 
            } 
        }
 
        public override Assembly Assembly
        {
            get
            { 
                return GetTypeHandleInternal().GetAssemblyHandle().GetAssembly();
            } 
        } 

        public override RuntimeTypeHandle TypeHandle 
        {
            get
            {
                return m_handle; 
            }
        } 
 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        internal override RuntimeTypeHandle GetTypeHandleInternal() 
        {
            return m_handle;
        }
 
        internal override TypeCode GetTypeCodeInternal()
        { 
            TypeCode typeCode = Cache.TypeCode; 

            if (typeCode != TypeCode.Empty) 
                return typeCode;

            CorElementType corElementType = GetTypeHandleInternal().GetCorElementType();
            switch (corElementType) 
            {
                case CorElementType.Boolean: 
                    typeCode = TypeCode.Boolean; break; 
                case CorElementType.Char:
                    typeCode = TypeCode.Char; break; 
                case CorElementType.I1:
                    typeCode = TypeCode.SByte; break;
                case CorElementType.U1:
                    typeCode = TypeCode.Byte; break; 
                case CorElementType.I2:
                    typeCode = TypeCode.Int16; break; 
                case CorElementType.U2: 
                    typeCode = TypeCode.UInt16; break;
                case CorElementType.I4: 
                    typeCode = TypeCode.Int32; break;
                case CorElementType.U4:
                    typeCode = TypeCode.UInt32; break;
                case CorElementType.I8: 
                    typeCode = TypeCode.Int64; break;
                case CorElementType.U8: 
                    typeCode = TypeCode.UInt64; break; 
                case CorElementType.R4:
                    typeCode = TypeCode.Single; break; 
                case CorElementType.R8:
                    typeCode = TypeCode.Double; break;
                case CorElementType.String:
                    typeCode = TypeCode.String; break; 
                case CorElementType.ValueType:
                    if (this == Convert.ConvertTypes[(int)TypeCode.Decimal]) 
                        typeCode = TypeCode.Decimal; 
                    else if (this == Convert.ConvertTypes[(int)TypeCode.DateTime])
                        typeCode = TypeCode.DateTime; 
                    else if (this.IsEnum)
                        typeCode = Type.GetTypeCode(Enum.GetUnderlyingType(this));
                    else
                        typeCode = TypeCode.Object; 
                    break;
                default: 
                    if (this == Convert.ConvertTypes[(int)TypeCode.DBNull]) 
                        typeCode = TypeCode.DBNull;
                    else if (this == Convert.ConvertTypes[(int)TypeCode.String]) 
                        typeCode = TypeCode.String;
                    else
                        typeCode = TypeCode.Object;
                    break; 
            }
 
            Cache.TypeCode = typeCode; 

            return typeCode; 
        }

        public override MethodBase DeclaringMethod
        { 
            get
            { 
                if (!IsGenericParameter) 
                    throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
 
                RuntimeMethodHandle declaringMethod = GetTypeHandleInternal().GetDeclaringMethod();

                if (declaringMethod.IsNullHandle())
                    return null; 

                return GetMethodBase(declaringMethod.GetDeclaringType(), declaringMethod); 
            } 
        }
        #endregion 

        #region Hierarchy
        public override bool IsInstanceOfType(Object o)
        { 
            return GetTypeHandleInternal().IsInstanceOfType(o);
        } 
 
[System.Runtime.InteropServices.ComVisible(true)]
        public override bool IsSubclassOf(Type type) 
        {
            if (type == null)
                throw new ArgumentNullException("type");
            ASSERT.PRECONDITION(type is RuntimeType); 

            Type baseType = BaseType; 
 
            while (baseType != null)
            { 
                if (baseType == type)
                    return true;

                baseType = baseType.BaseType; 
            }
 
            // pretty much everything is a subclass of object, even interfaces 
            // notice that interfaces are really odd because they do not have a BaseType
            // yet IsSubclassOf(typeof(object)) returns true 
            if (type == typeof(Object) && type != this)
                return true;

            return false; 
        }
 
        public override Type BaseType 
        {
            get 
            {
                if (IsInterface)
                    return null;
 
                if (m_handle.IsGenericVariable())
                { 
                    Type[] constraints = GetGenericParameterConstraints(); 

                    Type baseType = typeof(object); 

                    for (int i = 0; i < constraints.Length; i++)
                    {
                        Type constraint = 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 == typeof(object)) 
                    {
                        GenericParameterAttributes special; 
                        special = GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask; 
                        if ((special & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
                            baseType = typeof(ValueType); 
                    }

                    return baseType;
                } 

                return m_handle.GetBaseTypeHandle().GetRuntimeType(); 
            } 
        }
 
        public override Type UnderlyingSystemType
        {
            get
            { 
                // Origional Comment: Return the underlying Type that represents the IReflect Object.
                // For expando object, this is the (Object) IReflectInstance.GetType().  For Type object it is this. 
                return this; 
            }
        } 
        #endregion

        #region Name
        public override String FullName 
        {
            get 
            { 
                return Cache.GetFullName();
            } 
        }

        public override String AssemblyQualifiedName
        { 
            get
            { 
                if (!IsGenericTypeDefinition && ContainsGenericParameters) 
                    return null;
 
                return Assembly.CreateQualifiedName(this.Assembly.FullName, this.FullName);
            }
        }
 
        public override String Namespace
        { 
            get 
            {
                string ns = Cache.GetNameSpace(); 

                if (ns == null || ns.Length == 0)
                    return null;
 
                return ns;
            } 
        } 
        #endregion
 
        #region Attributes
        protected override TypeAttributes GetAttributeFlagsImpl()
        {
            return m_handle.GetAttributes(); 
        }
 
        public override Guid GUID 
        {
            get 
            {
                Guid result = new Guid ();
                GetGUID(ref result);
                return result; 
            }
        } 
 
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private extern void GetGUID(ref Guid result); 

        protected override bool IsContextfulImpl()
        {
            return GetTypeHandleInternal().IsContextful(); 
        }
 
        /* 
        protected override bool IsMarshalByRefImpl()
        { 
            return GetTypeHandleInternal().IsMarshalByRef();
        }
        */
 
        protected override bool IsByRefImpl()
        { 
            CorElementType corElemType = GetTypeHandleInternal().GetCorElementType(); 
            return (corElemType == CorElementType.ByRef);
        } 

        protected override bool IsPrimitiveImpl()
        {
            CorElementType corElemType = GetTypeHandleInternal().GetCorElementType(); 

            return 
                (corElemType >= CorElementType.Boolean && corElemType <= CorElementType.R8) || 
                corElemType == CorElementType.I ||
                corElemType == CorElementType.U; 
        }

        protected override bool IsPointerImpl()
        { 
            CorElementType corElemType = GetTypeHandleInternal().GetCorElementType();
            return (corElemType == CorElementType.Ptr); 
        } 

        protected override bool IsCOMObjectImpl() 
        {
            return GetTypeHandleInternal().IsComObject(false);
        }
 
        internal override bool HasProxyAttributeImpl()
        { 
            return GetTypeHandleInternal().HasProxyAttribute(); 
        }
 
        protected override bool HasElementTypeImpl()
        {
            return (IsArray || IsPointer || IsByRef);
        } 

        public override GenericParameterAttributes GenericParameterAttributes 
        { 
            get
            { 
                if (!IsGenericParameter)
                    throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));

                GenericParameterAttributes attributes; 

                GetTypeHandleInternal().GetModuleHandle().GetMetadataImport().GetGenericParamProps(MetadataToken, out attributes); 
 
                return attributes;
            } 
        }
        #endregion

        #region Arrays 
        internal override bool IsSzArray
        { 
            get 
            {
                CorElementType corElemType = GetTypeHandleInternal().GetCorElementType(); 
                return (corElemType == CorElementType.SzArray);
            }
        }
 
        protected override bool IsArrayImpl()
        { 
            CorElementType corElemType = GetTypeHandleInternal().GetCorElementType(); 
            return (corElemType == CorElementType.Array || corElemType == CorElementType.SzArray);
        } 

        public override int GetArrayRank()
        {
            if (!IsArrayImpl()) 
                throw new ArgumentException(Environment.GetResourceString("Argument_HasToBeArrayClass"));
 
            return GetTypeHandleInternal().GetArrayRank(); 
        }
 
        public override Type GetElementType()
        {
            return GetTypeHandleInternal().GetElementType().GetRuntimeType();
        } 
        #endregion
 
        #region Generics 
        public override Type[] GetGenericArguments()
        { 
            Type[] rtypes = null;
            RuntimeTypeHandle[] types = GetRootElementType().GetTypeHandleInternal().GetInstantiation();

            if (types != null) 
            {
                rtypes = new Type[types.Length]; 
 
                for (int i = 0; i < types.Length; i++)
                    rtypes[i] = types[i].GetRuntimeType(); 
            }
            else
            {
                rtypes = new Type[0]; 
            }
 
            return rtypes; 
        }
 
        public override Type MakeGenericType(Type[] instantiation)
        {
            if (instantiation == null)
                throw new ArgumentNullException("instantiation"); 

            Type[] instantiationCopy = new Type[instantiation.Length]; 
            for (int i = 0; i < instantiation.Length; i ++) 
                instantiationCopy[i] = instantiation[i];
            instantiation = instantiationCopy; 

            if (!IsGenericTypeDefinition)
                throw new InvalidOperationException(
                    String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Arg_NotGenericTypeDefinition"), this)); 

            for (int i = 0; i < instantiation.Length; i ++) 
            { 
                if (instantiation[i] == null)
                    throw new ArgumentNullException(); 

                if (!(instantiation[i] is RuntimeType))
                    return new TypeBuilderInstantiation(this, instantiation);
            } 

            Type[] genericParameters = GetGenericArguments(); 
 
            SanityCheckGenericArguments(instantiation, genericParameters);
 
            RuntimeTypeHandle[] typeHandles = new RuntimeTypeHandle[instantiation.Length];

            for (int i = 0; i < instantiation.Length; i++)
                typeHandles[i] = instantiation[i].GetTypeHandleInternal(); 

            Type ret = null; 
            try 
            {
                ret = m_handle.Instantiate(typeHandles).GetRuntimeType(); 
            }
            catch (TypeLoadException e)
            {
                ValidateGenericArguments(this, instantiation, e); 
                throw e;
            } 
 
            return ret;
        } 

        public override bool IsGenericTypeDefinition
        {
            get { return m_handle.IsGenericTypeDefinition(); } 
        }
 
        public override bool IsGenericParameter 
        {
            get { return m_handle.IsGenericVariable(); } 
        }

        public override int GenericParameterPosition
        { 
            get
            { 
                if (!IsGenericParameter) 
                    throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
 
                return m_handle.GetGenericVariableIndex();
            }
        }
 
        public override Type GetGenericTypeDefinition()
        { 
            if (!IsGenericType) 
                throw new InvalidOperationException();
 
            return m_handle.GetGenericTypeDefinition().GetRuntimeType();
        }

      	public override bool IsGenericType 
        {
            get { return HasElementType ? false : GetTypeHandleInternal().HasInstantiation(); } 
        } 

        public override bool ContainsGenericParameters 
        {
            get { return GetRootElementType().GetTypeHandleInternal().ContainsGenericVariables(); }
        }
 
        public override Type[] GetGenericParameterConstraints()
        { 
            if (!IsGenericParameter) 
                throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
 
            RuntimeTypeHandle[] constraintHandles = m_handle.GetConstraints();
            Type[] constraints = new Type[constraintHandles.Length];

            for (int i = 0; i < constraints.Length; i++) 
                constraints[i] = constraintHandles[i].GetRuntimeType();
 
            return constraints; 
        }
        #endregion 

        #region Misc
        public override Type MakePointerType() { return m_handle.MakePointer().GetRuntimeType(); }
        public override Type MakeByRefType() { return m_handle.MakeByRef().GetRuntimeType(); } 
        public override Type MakeArrayType() { return m_handle.MakeSZArray().GetRuntimeType(); }
        public override Type MakeArrayType(int rank) 
        { 
            if (rank <= 0)
                throw new IndexOutOfRangeException(); 

            return m_handle.MakeArray(rank).GetRuntimeType();
        }
        public override StructLayoutAttribute StructLayoutAttribute 
        {
            get 
            { 
                return (StructLayoutAttribute)StructLayoutAttribute.GetCustomAttribute(this);
            } 
        }
        #endregion

        #region Invoke Member 
        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 BinderSetInvokeProperty  = BindingFlags.InvokeMethod | BindingFlags.SetProperty; 
        private const BindingFlags BinderGetSetField        = BindingFlags.GetField | BindingFlags.SetField;
        private const BindingFlags BinderSetInvokeField     = BindingFlags.SetField | BindingFlags.InvokeMethod;
        private const BindingFlags BinderNonFieldGetSet     = (BindingFlags)0x00FFF300;
        private const BindingFlags ClassicBindingMask       = 
            BindingFlags.InvokeMethod | BindingFlags.GetProperty | BindingFlags.SetProperty |
            BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty; 
        private static Type s_typedRef = typeof(TypedReference); 

        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        static private extern bool CanValueSpecialCast(IntPtr valueType, IntPtr targetType);

        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        static private extern Object AllocateObjectForByRef(RuntimeTypeHandle type, object value); 

        internal unsafe Object CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr) 
        { 
            // this method is used by invocation in reflection to check whether a value can be assigned to type.
            if (IsInstanceOfType(value)) 
                return value;

            // if this is a ByRef get the element type and check if it's compatible
            bool isByRef = IsByRef; 
            if (isByRef)
            { 
                Type elementType = GetElementType(); 
                if (elementType.IsInstanceOfType(value) || value == null)
                { 
                    // need to create an instance of the ByRef if null was provided, but only if primitive, enum or value type
                    return AllocateObjectForByRef(elementType.TypeHandle, value);
                }
            } 
            else if (value == null)
                return value; 
            else if (this == s_typedRef) 
                // everything works for a typedref
                return value; 

            // check the strange ones courtesy of reflection:
            // - implicit cast between primitives
            // - enum treated as underlying type 
            // - IntPtr and System.Reflection.Pointer to pointer types
            bool needsSpecialCast = IsPointer || IsEnum || IsPrimitive; 
            if (needsSpecialCast) 
            {
                Type valueType; 
                Pointer pointer = value as Pointer;
                if (pointer != null)
                    valueType = pointer.GetPointerType();
                else 
                    valueType = value.GetType();
 
                if (CanValueSpecialCast(valueType.TypeHandle.Value, TypeHandle.Value)) 
                {
                    if (pointer != null) 
                        return pointer.GetPointerValue();
                    else
                        return value;
                } 
            }
 
            if ((invokeAttr & BindingFlags.ExactBinding) == BindingFlags.ExactBinding) 
                throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
 
            if (binder != null && binder != Type.DefaultBinder)
            {
                value = binder.ChangeType(value, this, culture);
                if (IsInstanceOfType(value)) 
                    return value;
                // if this is a ByRef get the element type and check if it's compatible 
                if (isByRef) 
                {
                    Type elementType = GetElementType(); 
                    if (elementType.IsInstanceOfType(value) || value == null)
                        return AllocateObjectForByRef(elementType.TypeHandle, value);
                }
                else if (value == null) 
                    return value;
                if (needsSpecialCast) 
                { 
                    Type valueType;
                    Pointer pointer = value as Pointer; 
                    if (pointer != null)
                        valueType = pointer.GetPointerType();
                    else
                        valueType = value.GetType(); 

                    if (CanValueSpecialCast(valueType.TypeHandle.Value, TypeHandle.Value)) 
                    { 
                        if (pointer != null)
                            return pointer.GetPointerValue(); 
                        else
                            return value;
                    }
                } 
            }
 
            throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this)); 
        }
 
        [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(Environment.GetResourceString("Arg_GenericParameter"));
 
            #region Preconditions
            if ((bindingFlags & InvocationMask) == 0)
                // "Must specify binding flags describing the invoke operation required."
                throw new ArgumentException(Environment.GetResourceString("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(Environment.GetResourceString("Arg_NamedParamTooBig"), "namedParams"); 
                }
                else 
                { 
                    if (namedParams.Length != 0)
                        // "Named parameter array can not be bigger than argument array." 
                        throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamTooBig"), "namedParams");
                }
            }
            #endregion 

            #region COM Interop 
#if FEATURE_COMINTEROP 
            if (target != null && target.GetType().IsCOMObject)
            { 
                #region Preconditions
                if ((bindingFlags & ClassicBindingMask) == 0)
                    throw new ArgumentException(Environment.GetResourceString("Arg_COMAccess"), "bindingFlags");
 
                if ((bindingFlags & BindingFlags.GetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
                    throw new ArgumentException(Environment.GetResourceString("Arg_PropSetGet"), "bindingFlags"); 
 
                if ((bindingFlags & BindingFlags.InvokeMethod) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
                    throw new ArgumentException(Environment.GetResourceString("Arg_PropSetInvoke"), "bindingFlags"); 

                if ((bindingFlags & BindingFlags.SetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.SetProperty) != 0)
                    throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags");
 
                if ((bindingFlags & BindingFlags.PutDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutDispProperty) != 0)
                    throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags"); 
 
                if ((bindingFlags & BindingFlags.PutRefDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutRefDispProperty) != 0)
                    throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags"); 
                #endregion

                if(!RemotingServices.IsTransparentProxy(target))
                { 
                    #region Non-TransparentProxy case
                    if (name == null) 
                        throw new ArgumentNullException("name"); 

                    if (culture == null) 
                        culture = Thread.CurrentThread.CurrentCulture;

                    bool[] isByRef = modifiers == null ? null : modifiers[0].IsByRefArray;
 
                    return InvokeDispMethod(name, bindingFlags, target, providedArgs, isByRef, culture.LCID, namedParams);
                    #endregion 
                } 
                else
                { 
                    #region TransparentProxy case
                    return ((MarshalByRefObject)target).InvokeMember(name, bindingFlags, binder, providedArgs, modifiers, culture, namedParams);
                    #endregion
                } 
            }
#endif // FEATURE_COMINTEROP 
            #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(Environment.GetResourceString("Arg_NamedParamNull"),"namedParams");
            #endregion 

            int argCnt = (providedArgs != null) ? providedArgs.Length : 0; 
 
            #region Get a Binder
            if (binder == null) 
                binder = DefaultBinder;

            bool bDefaultBinder = (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(Environment.GetResourceString("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(Environment.GetResourceString("Arg_FldSetGet"),"bindingFlags");
 
                    if ((bindingFlags & BindingFlags.SetProperty) != 0)
                        // "Can not specify both GetField and SetProperty." 
                        throw new ArgumentException(Environment.GetResourceString("Arg_FldGetPropSet"),"bindingFlags"); 
                }
                else 
                {
                    ASSERT.CONSISTENCY_CHECK(IsSetField);

                    if (providedArgs == null) 
                        throw new ArgumentNullException("providedArgs");
 
                    if ((bindingFlags & BindingFlags.GetProperty) != 0) 
                        // "Can not specify both SetField and GetProperty."
                        throw new ArgumentException(Environment.GetResourceString("Arg_FldSetPropGet"),"bindingFlags"); 

                    if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
                        // "Can not specify Set on a Field and Invoke on a method."
                        throw new ArgumentException(Environment.GetResourceString("Arg_FldSetInvoke"),"bindingFlags"); 
                }
                #endregion 
 
                #region Lookup Field
                FieldInfo selFld = null; 
                FieldInfo[] flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[];

                ASSERT.CONSISTENCY_CHECK(flds != null);
 
                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 || 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 1); 
                    finalists = new MethodInfo[results.Count];
                    results.CopyTo(finalists);
                }
                #endregion 
            }
            #endregion 
 
            ASSERT.CONSISTENCY_CHECK(LOGIC.IMPLIES(finalists != null, finalist != null));
 
            #region BindingFlags.GetProperty or BindingFlags.SetProperty
            if (finalist == null && isGetProperty || isSetProperty)
            {
                #region Lookup Property 
                PropertyInfo[] semiFinalists = GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[];
                ArrayList 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 (!FilterApplyMethodBaseInfo(semiFinalist, bindingFlags, null, CallingConventions.Any, new Type[argCnt], false)) 
                        continue; 

                    if (finalist == null) 
                    {
                        finalist = semiFinalist;
                    }
                    else 
                    {
                        if (results == null) 
                        { 
                            results = new ArrayList(semiFinalists.Length);
                            results.Add(finalist); 
                        }

                        results.Add(semiFinalist);
                    } 
                }
 
                if (results != null) 
                {
                    ASSERT.CONSISTENCY_CHECK(results.Count > 1); 
                    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 = new Object[0];
 
                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); 
        } 
        #endregion
 
        #endregion

        #region Object Overrides
        public override bool Equals(object obj) 
        {
            // ComObjects are identified by the instance of the Type object and not the TypeHandle. 
            return obj == this; 
        }
 
        public override int GetHashCode()
        {
            #if WIN32
                return (int)GetTypeHandleInternal().Value; 
            #else
                long l = (long)GetTypeHandleInternal().Value; 
                return unchecked((int)l); 
            #endif
        } 

        public override String ToString()
        {
            return Cache.GetToString(); 
        }
        #endregion 
 
        #region ICloneable
        public Object Clone() 
        {
            return this;
        }
        #endregion 

        #region ISerializable 
        public void GetObjectData(SerializationInfo info, StreamingContext context) 
        {
            if (info==null) 
                throw new ArgumentNullException("info");

            UnitySerializationHolder.GetUnitySerializationInfo(info, this);
        } 
        #endregion
 
        #region ICustomAttributeProvider 
        public override Object[] GetCustomAttributes(bool inherit)
        { 
            return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType, inherit);
        }

        public override Object[] GetCustomAttributes(Type attributeType, bool inherit) 
        {
            if (attributeType == null) 
                throw new ArgumentNullException("attributeType"); 

            RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; 

            if (attributeRuntimeType == null)
                throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
 
            return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit);
        } 
 
        public override bool IsDefined(Type attributeType, bool inherit)
        { 
            if (attributeType == null)
                throw new ArgumentNullException("attributeType");

            RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; 

            if (attributeRuntimeType == null) 
                throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType"); 

            return CustomAttribute.IsDefined(this, attributeRuntimeType, inherit); 
        }
        #endregion

        #region MemberInfo Overrides 
        public override String Name
        { 
            get 
            {
                return Cache.GetName(); 
            }
        }

        public override MemberTypes MemberType 
        {
            get 
            { 
                if (this.IsPublic || this.IsNotPublic)
                    return MemberTypes.TypeInfo; 
                else
                    return MemberTypes.NestedType;
            }
        } 

        public override Type DeclaringType 
        { 
            get
            { 
                return Cache.GetEnclosingType();
            }
        }
 
        public override Type ReflectedType
        { 
            get 
            {
                return DeclaringType; 
            }
        }

        public override int MetadataToken 
        {
            get 
            { 
                return m_handle.GetToken();
            } 
        }
        #endregion

        #region Legacy Internal 
        internal void CreateInstanceCheckThis()
        { 
            if (this is ReflectionOnlyType) 
                throw new ArgumentException(Environment.GetResourceString("Arg_ReflectionOnlyInvoke"));
 
            if (ContainsGenericParameters)
                throw new ArgumentException(
                    String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Acc_CreateGenericEx"), this));
 
            Type elementType = this.GetRootElementType();
 
            if (elementType == typeof(ArgIterator)) 
                throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Acc_CreateArgIterator")));
 
            if (elementType == typeof(void))
                throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Acc_CreateVoid")));
        }
 
        internal Object CreateInstanceImpl(
            BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) 
        { 
            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(null != activationAttributes)
                    {
                        ActivationServices.PushActivationAttributes(this, activationAttributes); 
                    }
 
                    if (args == null) 
                        args = new Object[0];
 
                    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
                    if (argCnt == 0 && (bindingAttr & BindingFlags.Public) != 0 && (bindingAttr & BindingFlags.Instance) != 0 
                        && (IsGenericCOMObjectImpl() || IsSubclassOf(typeof(ValueType))))
                    {
                            server = CreateInstanceImpl(((bindingAttr & BindingFlags.NonPublic) != 0) ? false : true);
                    } 
                    else
                    { 
                        MethodBase[] candidates = GetConstructors(bindingAttr); 
                        ArrayList matches = new ArrayList(candidates.Length);
                        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 ++)
                        {
                            MethodBase canidate = candidates[i];
 
                            if (FilterApplyMethodBaseInfo(
                                candidates[i], bindingAttr, null, CallingConventions.Any, argsType, false)) 
                                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
                            if(null != activationAttributes) 
                            {
                                ActivationServices.PopActivationAttributes(this);
                                activationAttributes = null;
                            } 
                            throw new MissingMethodException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("MissingConstructor_Name"), FullName));
                        } 
 
                        // It would be strange to have an argCnt of 0 and more than
                        //  one constructor. 
                        if (argCnt == 0 && cons.Length == 1 && (bindingAttr & BindingFlags.OptionalParamBinding) == 0)
                            server = Activator.CreateInstance(this, true);
                        else
                        { 
                            //      MethodBase invokeMethod = binder.BindToMethod(cons,args,null,null,culture);
                            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)
                            {
                                // Null out activation attributes before throwing exception 
                                if(null != activationAttributes)
                                { 
                                    ActivationServices.PopActivationAttributes(this); 
                                    activationAttributes = null;
                                } 
                                throw new MissingMethodException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("MissingConstructor_Name"), FullName));
                            }

                            // If we're creating a delegate, we're about to call a 
                            // constructor taking an integer to represent a target
                            // method. Since this is very difficult (and expensive) 
                            // to verify, we're just going to demand UnmanagedCode 
                            // permission before allowing this. Partially trusted
                            // clients can instead use Delegate.CreateDelegate, 
                            // which allows specification of the target method via
                            // name or MethodInfo.
                            //if (isDelegate)
                            if (typeof(Delegate).IsAssignableFrom(invokeMethod.DeclaringType)) 
                                new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
 
                            server = ((ConstructorInfo) invokeMethod).Invoke(bindingAttr,binder,args,culture); 
                            if (state != null)
                                binder.ReorderArgumentArray(ref args, state); 
                        }
                    }
                }
                finally 
                {
                    // Reset the TLS to null 
                    if(null != activationAttributes) 
                    {
                          ActivationServices.PopActivationAttributes(this); 
                          activationAttributes = null;
                    }
                }
            } 
            catch (Exception)
            { 
                throw; 
            }
 
            //Console.WriteLine(server);
            return server;
        }
 
        // the cache entry
        class ActivatorCacheEntry 
        { 
            // the type to cache
            internal Type m_type; 
            // the delegate containing the call to the ctor, will be replaced by an IntPtr to feed a calli with
            internal CtorDelegate m_ctor;
            internal RuntimeMethodHandle m_hCtorMethodHandle;
            // Is a security check needed before this constructor is invoked? 
            internal bool m_bNeedSecurityCheck;
            // Lazy initialization was performed 
            internal bool m_bFullyInitialized; 

            internal ActivatorCacheEntry(Type t, RuntimeMethodHandle rmh, bool bNeedSecurityCheck) 
            {
                m_type = t;
                m_bNeedSecurityCheck = bNeedSecurityCheck;
                m_hCtorMethodHandle = rmh; 
            }
        } 
 
        //ActivatorCache
        class ActivatorCache 
        {
            const int CACHE_SIZE = 16;
            int hash_counter; //Counter for wrap around
            ActivatorCacheEntry[] cache = new ActivatorCacheEntry[CACHE_SIZE]; 

            ConstructorInfo     delegateCtorInfo; 
            PermissionSet       delegateCreatePermissions; 

            private void InitializeDelegateCreator() { 
                // No synchronization needed here. In the worst case we create extra garbage
                PermissionSet ps = new PermissionSet(PermissionState.None);
                ps.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.MemberAccess));
                ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode)); 
                System.Threading.Thread.MemoryBarrier();
                delegateCreatePermissions = ps; 
 
                ConstructorInfo ctorInfo = typeof(CtorDelegate).GetConstructor(new Type[] {typeof(Object), typeof(IntPtr)});
                System.Threading.Thread.MemoryBarrier(); 
                delegateCtorInfo = ctorInfo; // this assignment should be last
            }

            private void InitializeCacheEntry(ActivatorCacheEntry ace) 
            {
                if (!ace.m_type.IsValueType) 
                { 
                    BCLDebug.Assert(!ace.m_hCtorMethodHandle.Equals(RuntimeMethodHandle.EmptyHandle), "Expected the default ctor method handle for a reference type.");
 
                    if (delegateCtorInfo == null)
                        InitializeDelegateCreator();
                    delegateCreatePermissions.Assert();
 
                    // No synchronization needed here. In the worst case we create extra garbage
                    CtorDelegate ctor = (CtorDelegate)delegateCtorInfo.Invoke(new Object[] {null, ace.m_hCtorMethodHandle.GetFunctionPointer()}); 
                    System.Threading.Thread.MemoryBarrier(); 
                    ace.m_ctor = ctor;
                } 
                ace.m_bFullyInitialized = true;
            }

            internal ActivatorCacheEntry GetEntry(Type t) 
            {
                int index = hash_counter; 
                for(int i = 0; i < CACHE_SIZE; i++) 
                {
                    ActivatorCacheEntry ace = cache[index]; 
                    if (ace != null && (Object)ace.m_type == (Object)t) //check for type match..
                    {
                        if (!ace.m_bFullyInitialized)
                            InitializeCacheEntry(ace); 
                        return ace;
                    } 
                    index = (index+1)&(ActivatorCache.CACHE_SIZE-1); 
                }
                return null; 
            }

            internal void SetEntry(ActivatorCacheEntry ace)
            { 
                // fill the the array backwards to hit the most recently filled entries first in GetEntry
                int index = (hash_counter-1)&(ActivatorCache.CACHE_SIZE-1); 
                hash_counter = index; 
                cache[index] = ace;
            } 
        }

        static ActivatorCache s_ActivatorCache;
 
        // the slow path of CreateInstanceImpl
        private Object CreateInstanceSlow(bool publicOnly, bool fillCache) 
        { 
            RuntimeMethodHandle runtime_ctor = RuntimeMethodHandle.EmptyHandle;
            bool bNeedSecurityCheck = true; 
            bool bCanBeCached = false;
            bool bSecurityCheckOff = false;

            CreateInstanceCheckThis(); 

            if (!fillCache) 
                bSecurityCheckOff = true; 

            Object instance = RuntimeTypeHandle.CreateInstance(this, publicOnly, bSecurityCheckOff, ref bCanBeCached, ref runtime_ctor, ref bNeedSecurityCheck); 

            if (bCanBeCached && fillCache)
            {
                ActivatorCache activatorCache = s_ActivatorCache; 
                if(activatorCache == null)
                { 
                    // No synchronization needed here. In the worst case we create extra garbage 
                    activatorCache = new ActivatorCache();
                    System.Threading.Thread.MemoryBarrier(); 
                    s_ActivatorCache = activatorCache;
                }

                // cache the ctor 
                ActivatorCacheEntry ace = new ActivatorCacheEntry(this, runtime_ctor, bNeedSecurityCheck);
                System.Threading.Thread.MemoryBarrier(); 
                activatorCache.SetEntry(ace); 
            }
            return instance; 
        }

        [DebuggerStepThroughAttribute]
        [Diagnostics.DebuggerHidden] 
        internal Object CreateInstanceImpl(bool publicOnly)
        { 
            return CreateInstanceImpl(publicOnly, false, true); 
        }
 
        [DebuggerStepThroughAttribute]
        [Diagnostics.DebuggerHidden]
        internal Object CreateInstanceImpl(bool publicOnly, bool skipVisibilityChecks, bool fillCache)
        { 
            // next line will throw for ReflectionOnly types
            RuntimeTypeHandle typeHandle = TypeHandle; 
            ActivatorCache activatorCache = s_ActivatorCache; 
            if (activatorCache != null)
            { 
                ActivatorCacheEntry ace = activatorCache.GetEntry(this);
                if (ace != null)
                {
                    if (publicOnly) 
                    {
                        if (ace.m_ctor != null && 
                            (ace.m_hCtorMethodHandle.GetAttributes() & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) 
                        {
                            throw new MissingMethodException(Environment.GetResourceString("Arg_NoDefCTor")); 
                        }
                    }

                    // Allocate empty object 
                    Object instance = typeHandle.Allocate();
                    if (ace.m_ctor != null) 
                    { 
                        // Perform security checks if needed
                        if (!skipVisibilityChecks && ace.m_bNeedSecurityCheck) 
                        {
                            MethodBase.PerformSecurityCheck(instance, ace.m_hCtorMethodHandle, TypeHandle.Value, INVOCATION_FLAGS_CONSTRUCTOR_INVOKE);
                        }
                        // Call ctor (value types wont have any) 
                        try
                        { 
                            ace.m_ctor(instance); 
                        }
                        catch (Exception e) 
                        {
                            throw new TargetInvocationException(e);
                        }
                    } 
                    return instance;
                } 
            } 
            return CreateInstanceSlow(publicOnly, fillCache);
        } 

    //End

        internal bool SupportsInterface(Object o) 
        {
            return TypeHandle.SupportsInterface(o); 
        } 

        internal void InvalidateCachedNestedType() 
        {
            Cache.InvalidateCachedNestedType();
        }
 
        internal bool IsGenericCOMObjectImpl()
        { 
            return m_handle.IsComObject(true); 
        }
        #endregion 

        #region Legacy Static Internal
        internal static bool CanCastTo(RuntimeType fromType, RuntimeType toType)
        { 
            return fromType.GetTypeHandleInternal().CanCastTo(toType.GetTypeHandleInternal());
        } 
 
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private static extern Object _CreateEnum(IntPtr enumType, long value); 
        internal static Object CreateEnum(RuntimeTypeHandle enumType, long value) {
            return _CreateEnum(enumType.Value, value);
        }
 
#if FEATURE_COMINTEROP
        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        private extern Object InvokeDispMethod( 
            String name, BindingFlags invokeAttr, Object target, Object[] args,
            bool[] byrefModifiers, int culture, String[] namedParameters); 

        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal static extern Type GetTypeFromProgIDImpl(String progID, String server, bool throwOnError);
 
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal static extern Type GetTypeFromCLSIDImpl(Guid clsid, String server, bool throwOnError); 
#endif 

        internal static Type PrivateGetType(String typeName, bool throwOnError, bool ignoreCase, 
            ref StackCrawlMark stackMark)
        {
            return PrivateGetType(typeName, throwOnError, ignoreCase, false, ref stackMark);
        } 

        internal static Type PrivateGetType(String typeName, bool throwOnError, bool ignoreCase, bool reflectionOnly, 
            ref StackCrawlMark stackMark) 
        {
            unsafe 
            {
                if (typeName == null)
                    throw new ArgumentNullException("TypeName");
 
                return RuntimeTypeHandle.GetTypeByName(
                    typeName, throwOnError, ignoreCase, reflectionOnly, ref stackMark).GetRuntimeType(); 
            } 
        }
 
        #endregion

        #region COM
#if FEATURE_COMINTEROP 
        private Object ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, int[] aWrapperTypes, ref MessageData msgData)
        { 
            ParameterModifier[] aParamMod = null; 
            Object ret = null;
 
            // Allocate a new message
            Message reqMsg = new Message();
            reqMsg.InitFields(msgData);
 
            // Retrieve the required information from the message object.
            MethodInfo meth = (MethodInfo)reqMsg.GetMethodBase(); 
            Object[] aArgs = reqMsg.Args; 
            int cArgs = aArgs.Length;
 
            // Retrieve information from the method we are invoking on.
            ParameterInfo[] aParams = meth.GetParametersNoCopy();

            // If we have arguments, then set the byref flags to true for byref arguments. 
            // We also wrap the arguments that require wrapping.
            if (cArgs > 0) 
            { 
                ParameterModifier paramMod = new ParameterModifier(cArgs);
                for (int i = 0; i < cArgs; i++) 
                {
                    if (aParams[i].ParameterType.IsByRef)
                        paramMod[i] = true;
                } 

                aParamMod = new ParameterModifier[1]; 
                aParamMod[0] = paramMod; 

                if (aWrapperTypes != null) 
                    WrapArgsForInvokeCall(aArgs, aWrapperTypes);
            }

            // If the method has a void return type, then set the IgnoreReturn binding flag. 
            if (meth.ReturnType == typeof(void))
                flags |= BindingFlags.IgnoreReturn; 
 
            try
            { 
                // Invoke the method using InvokeMember().
                ret = InvokeMember(memberName, flags, null, target, aArgs, aParamMod, null, null);
            }
            catch (TargetInvocationException e) 
            {
                // For target invocation exceptions, we need to unwrap the inner exception and 
                // re-throw it. 
                throw e.InnerException;
            } 

            // Convert each byref argument that is not of the proper type to
            // the parameter type using the OleAutBinder.
            for (int i = 0; i < cArgs; i++) 
            {
                if (aParamMod[0][i] && aArgs[i] != null) 
                { 
                    // The parameter is byref.
                    Type paramType = aParams[i].ParameterType.GetElementType(); 
                    if (paramType != aArgs[i].GetType())
                        aArgs[i] = ForwardCallBinder.ChangeType(aArgs[i], paramType, null);
                }
            } 

            // If the return type is not of the proper type, then convert it 
            // to the proper type using the OleAutBinder. 
            if (ret != null)
            { 
                Type retType = meth.ReturnType;
                if (retType != ret.GetType())
                    ret = ForwardCallBinder.ChangeType(ret, retType, null);
            } 

            // Propagate the out parameters 
            RealProxy.PropagateOutParameters(reqMsg, aArgs, ret); 

            // Return the value returned by the InvokeMember call. 
            return ret;
        }

        private void WrapArgsForInvokeCall(Object[] aArgs, int[] aWrapperTypes) 
        {
            int cArgs = aArgs.Length; 
            for (int i = 0; i < cArgs; i++) 
            {
                if (aWrapperTypes[i] == 0) 
                    continue;

                if (((DispatchWrapperType)aWrapperTypes[i] & DispatchWrapperType.SafeArray) != 0)
                { 
                    Type wrapperType = null;
                    bool isString = false; 
 
                    // Determine the type of wrapper to use.
                    switch ((DispatchWrapperType)aWrapperTypes[i] & ~DispatchWrapperType.SafeArray) 
                    {
                        case DispatchWrapperType.Unknown:
                            wrapperType = typeof(UnknownWrapper);
                            break; 
                        case DispatchWrapperType.Dispatch:
                            wrapperType = typeof(DispatchWrapper); 
                            break; 
                        case DispatchWrapperType.Error:
                            wrapperType = typeof(ErrorWrapper); 
                            break;
                        case DispatchWrapperType.Currency:
                            wrapperType = typeof(CurrencyWrapper);
                            break; 
                        case DispatchWrapperType.BStr:
                            wrapperType = typeof(BStrWrapper); 
                            isString = true; 
                            break;
                        default: 
                            BCLDebug.Assert(false, "[RuntimeType.WrapArgsForInvokeCall]Invalid safe array wrapper type specified.");
                            break;
                    }
 
                    // Allocate the new array of wrappers.
                    Array oldArray = (Array)aArgs[i]; 
                    int numElems = oldArray.Length; 
                    Object[] newArray = (Object[])Array.CreateInstance(wrapperType, numElems);
 
                    // Retrieve the ConstructorInfo for the wrapper type.
                    ConstructorInfo wrapperCons;
                    if(isString)
                    { 
                         wrapperCons = wrapperType.GetConstructor(new Type[] {typeof(String)});
                    } 
                    else 
                    {
                         wrapperCons = wrapperType.GetConstructor(new Type[] {typeof(Object)}); 
                    }

                    // Wrap each of the elements of the array.
                    for (int currElem = 0; currElem < numElems; currElem++) 
                    {
                        if(isString) 
                        { 
                            newArray[currElem] = wrapperCons.Invoke(new Object[] {(String)oldArray.GetValue(currElem)});
                        } 
                        else
                        {
                            newArray[currElem] = wrapperCons.Invoke(new Object[] {oldArray.GetValue(currElem)});
                        } 
                    }
 
                    // Update the argument. 
                    aArgs[i] = newArray;
                } 
                else
                {
                    // Determine the wrapper to use and then wrap the argument.
                    switch ((DispatchWrapperType)aWrapperTypes[i]) 
                    {
                        case DispatchWrapperType.Unknown: 
                            aArgs[i] = new UnknownWrapper(aArgs[i]); 
                            break;
                        case DispatchWrapperType.Dispatch: 
                            aArgs[i] = new DispatchWrapper(aArgs[i]);
                            break;
                        case DispatchWrapperType.Error:
                            aArgs[i] = new ErrorWrapper(aArgs[i]); 
                            break;
                        case DispatchWrapperType.Currency: 
                            aArgs[i] = new CurrencyWrapper(aArgs[i]); 
                            break;
                        case DispatchWrapperType.BStr: 
                            aArgs[i] = new BStrWrapper((String)aArgs[i]);
                            break;
                        default:
                            BCLDebug.Assert(false, "[RuntimeType.WrapArgsForInvokeCall]Invalid wrapper type specified."); 
                            break;
                    } 
                } 
            }
        } 

        private OleAutBinder ForwardCallBinder
        {
            get 
            {
                // Synchronization is not required. 
                if (s_ForwardCallBinder == null) 
                    s_ForwardCallBinder = new OleAutBinder();
 
                return s_ForwardCallBinder;
            }
        }
 
        [Flags]
        private enum DispatchWrapperType : int 
        { 
            // This enum must stay in [....] with the DispatchWrapperType enum defined in MLInfo.h
            Unknown         = 0x00000001, 
            Dispatch        = 0x00000002,
            Record          = 0x00000004,
            Error           = 0x00000008,
            Currency        = 0x00000010, 
            BStr            = 0x00000020,
            SafeArray       = 0x00010000 
        } 

        private static OleAutBinder s_ForwardCallBinder; 
#endif // FEATURE_COMINTEROP
        #endregion
    }
 
    // this is the introspection only type. This type overrides all the functions with runtime semantics
    // and throws an exception. 
    // The idea behind this type is that it relieves RuntimeType from doing honerous checks about ReflectionOnly 
    // context.
    // This type should not derive from RuntimeType but it's doing so for convinience. 
    // That should not present a security threat though it is risky as a direct call to one of the base method
    // method (RuntimeType) and an instance of this type will work around the reason to have this type in the
    // first place. However given RuntimeType is not public all its methods are protected and require full trust
    // to be accessed 
    [Serializable()]
    internal class ReflectionOnlyType : RuntimeType { 
 
        private ReflectionOnlyType() {}
 
       // always throw
        public override RuntimeTypeHandle TypeHandle
        {
            get 
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly")); 
            } 
        }
 
    }

    namespace Reflection
    { 
        [Serializable]
        internal sealed class CerArrayList 
        { 
            private const int MinSize = 4;
 
            private V[] m_array;
            private int m_count;

            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
            internal CerArrayList(List list)
            { 
                m_array = new V[list.Count]; 
                for (int i = 0; i < list.Count; i ++)
                    m_array[i] = list[i]; 
                m_count = list.Count;
            }

            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
            internal CerArrayList(int length)
            { 
                if (length < MinSize) 
                    length = MinSize;
 
                m_array = new V[length];
                m_count = 0;
            }
 
            internal int Count
            { 
                [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
                get { return m_count; }
            } 

            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
            internal void Preallocate(int addition)
            { 
                if (m_array.Length - m_count > addition)
                    return; 
 
                int newSize = m_array.Length * 2 > m_array.Length + addition ? m_array.Length * 2 : m_array.Length + addition;
 
                V[] newArray = new V[newSize];

                for (int i = 0; i < m_count; i++)
                { 
                    newArray[i] = m_array[i];
                } 
 
                m_array = newArray;
            } 

            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
            internal void Add(V value) { m_array[m_count] = value; m_count++; }
 
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
            internal void Replace(int index, V value) 
            { 
                if (index >= m_count)
                    throw new InvalidOperationException(); 

                m_array[index] = value;
            }
 
            internal V this[int index]
            { 
                [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
                get { return m_array[index]; }
            } 
        }

        [Serializable]
        internal sealed class CerHashtable 
        {
            private K[] m_key; 
            private V[] m_value; 
            private int m_count;
 
            private const int MinSize = 7;

            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
            internal CerHashtable() : this(MinSize) { } 

            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
            internal CerHashtable(int size) 
            {
                size = HashHelpers.GetPrime(size); 
                m_key = new K[size];
                m_value = new V[size];
            }
 
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
            internal void Preallocate(int count) 
            { 
                bool tookLock = false;
                bool success = false; 
                K[] newKeys = null;;
                V[] newValues = null;
                RuntimeHelpers.PrepareConstrainedRegions();
                try { 
                    Monitor.ReliableEnter(this, ref tookLock);
                    int newSize = (count + m_count) * 2; 
 
                    if (newSize < m_value.Length)
                        return; 

                    newSize = HashHelpers.GetPrime(newSize);

                    newKeys = new K[newSize]; 
                    newValues = new V[newSize];
 
                    for (int i = 0; i < m_key.Length; i++) 
                    {
                        K key = m_key[i]; 

                        if (key != null)
                        {
                            int dummyCount = 0; 
                            Insert(newKeys, newValues, ref dummyCount, key, m_value[i]);
                        } 
                    } 

                    success = true; 
                }
                finally {
                    if (success)
                    { 
                        m_key = newKeys;
                        m_value = newValues; 
                    } 

                    if (tookLock) 
                        Monitor.Exit(this);
                }
            }
 
            // Written as a static so we can share this code from Set and
            // Preallocate, which adjusts the data structure in place. 
            // Returns whether we inserted the item into a new slot or reused 
            // an existing hash table bucket.
            // Reliability-wise, we don't guarantee that the updates to the key 
            // and value arrays are done atomically within a CER.  Either
            // add your own CER or use temporary copies of this data structure.
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
            private static void Insert(K[] keys, V[] values, ref int count, K key, V value) 
            {
                int hashcode = key.GetHashCode(); 
                if (hashcode < 0) 
                    hashcode = -hashcode;
                int firstIndex = hashcode % keys.Length; 
                int index = firstIndex;

                while (true)
                { 
                    K hit = keys[index];
 
                    if ((object)hit == null) 
                    {
                        RuntimeHelpers.PrepareConstrainedRegions(); 
                        try { }
                        finally
                        {
                            keys[index] = key; 
                            values[index] = value;
                            count++; 
                        } 

                        break; 
                    }
                    else if (hit.Equals(key))  // Replace existing item
                    {
                        //BCLDebug.Assert(false, "Key was already in CerHashtable!  Potential ---- (or bug) in the Reflection cache?"); 
                        throw new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicate__", hit, key));
                        // If we wanted to make this more general, do this: 
                        /* 
                        values[index] = value;
                        usedNewSlot = false; 
                        */
                        //break;
                    }
                    else 
                    {
                        index++; 
                        index %= keys.Length; 
                    }
                } 
            }

            internal V this[K key]
            { 
                [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
                set 
                { 
                    bool tookLock = false;
                    RuntimeHelpers.PrepareConstrainedRegions(); 
                    try
                    {
                        Monitor.ReliableEnter(this, ref tookLock);
                        Insert(m_key, m_value, ref m_count, key, value); 
                    }
                    finally 
                    { 
                        if (tookLock)
                            Monitor.Exit(this); 
                    }
                }
                [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
                get 
                {
                    bool tookLock = false; 
 
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try 
                    {
                        Monitor.ReliableEnter(this, ref tookLock);

                        int hashcode = key.GetHashCode(); 
                        if (hashcode < 0)
                            hashcode = -hashcode; 
                        int firstIndex = hashcode % m_key.Length; 
                        int index = firstIndex;
 
                        while (true)
                        {
                            K hit = m_key[index];
 
                            if ((object)hit != null)
                            { 
                                if (hit.Equals(key)) 
                                    return m_value[index];
 
                                index++;
                                index %= m_key.Length;
                            }
                            else 
                            {
                                return default(V); 
                            } 
                        }
                    } 
                    finally
                    {
                        if (tookLock)
                            Monitor.Exit(this); 
                    }
 
                } 
            }
        } 
    }

    #region Library
    internal unsafe struct Utf8String 
    {
        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        private static extern unsafe bool EqualsCaseSensitive(void* szLhs, void* szRhs, int cSz); 

        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        private static extern unsafe bool EqualsCaseInsensitive(void* szLhs, void* szRhs, int cSz);

        private static int GetUtf8StringByteLength(void* pUtf8String)
        { 
            int len = 0;
 
            unsafe 
            {
                byte * pItr = (byte*)pUtf8String; 

                while (*pItr != 0)
                {
                    len++; 
                    pItr++;
                } 
            } 

            return len; 
        }

        private void* m_pStringHeap;        // This is the raw UTF8 string.
        private int m_StringHeapByteLength; 

        internal Utf8String(void* pStringHeap) 
        { 
            m_pStringHeap = pStringHeap;
            if (pStringHeap != null) 
            {
                m_StringHeapByteLength = GetUtf8StringByteLength(pStringHeap);
            }
            else 
            {
                m_StringHeapByteLength = 0; 
            } 
        }
 
        internal unsafe Utf8String(void* pUtf8String, int cUtf8String)
        {
              m_pStringHeap = pUtf8String;
              m_StringHeapByteLength = cUtf8String; 
        }
 
        internal unsafe bool Equals(Utf8String s) 
        {
            if (m_pStringHeap == null) 
            {
                return s.m_StringHeapByteLength == 0;
            }
            if ((s.m_StringHeapByteLength == m_StringHeapByteLength) && (m_StringHeapByteLength != 0)) 
            {
                return Utf8String.EqualsCaseSensitive(s.m_pStringHeap, m_pStringHeap, m_StringHeapByteLength); 
            } 
            return false;
        } 

        internal unsafe bool EqualsCaseInsensitive(Utf8String s)
        {
              if (m_pStringHeap == null) 
              {
                    return s.m_StringHeapByteLength == 0; 
              } 
              if ((s.m_StringHeapByteLength == m_StringHeapByteLength) && (m_StringHeapByteLength != 0))
              { 
                    return Utf8String.EqualsCaseInsensitive(s.m_pStringHeap, m_pStringHeap, m_StringHeapByteLength);
              }
              return false;
        } 

        public override string ToString() 
        { 
            unsafe
            { 
                byte* buf = stackalloc byte[m_StringHeapByteLength];
                byte * pItr = (byte*)m_pStringHeap;

                for (int currentPos = 0; currentPos < m_StringHeapByteLength; currentPos++) 
                {
                    buf[currentPos] = *pItr; 
                    pItr++; 
                }
 
                if (m_StringHeapByteLength == 0)
                    return "";

                int cResult = Encoding.UTF8.GetCharCount(buf, m_StringHeapByteLength); 
                char* result = stackalloc char[cResult];
                Encoding.UTF8.GetChars(buf, m_StringHeapByteLength, result, cResult); 
                return new string(result, 0, cResult); 
            }
        } 
    }

    internal sealed class ASSERT : Exception
    { 
        #region FRIEND
        private static bool AssertIsFriend(Type[] friends, StackTrace st) 
        { 
            Type typeOfCallee = st.GetFrame(1).GetMethod().DeclaringType;
            Type typeOfCaller = st.GetFrame(2).GetMethod().DeclaringType; 

            bool noFriends = true;
            foreach(Type friend in friends)
            { 
                if (typeOfCaller != friend && typeOfCaller != typeOfCallee)
                    noFriends = false; 
            } 

            if (noFriends) 
                Assert(false, Environment.GetResourceString("RtType.InvalidCaller"), st.ToString());

            return true;
        } 
        [Conditional("_DEBUG")]
        internal static void FRIEND(Type[] friends) 
        { 
            StackTrace st = new StackTrace();
            AssertIsFriend(friends, st); 
        }
        [Conditional("_DEBUG")]
        internal static void FRIEND(Type friend)
        { 
            StackTrace st = new StackTrace();
            AssertIsFriend(new Type[] {friend}, st); 
        } 
        [Conditional("_DEBUG")]
        internal static void FRIEND(string ns) 
        {
            StackTrace st = new StackTrace();
            string nsOfCallee = st.GetFrame(1).GetMethod().DeclaringType.Namespace;
            string nsOfCaller = st.GetFrame(2).GetMethod().DeclaringType.Namespace; 
            Assert(nsOfCaller.Equals(nsOfCaller) || nsOfCaller.Equals(ns), Environment.GetResourceString("RtType.InvalidCaller"), st.ToString());
        } 
        #endregion 

        #region PRECONDITION 
        [Conditional("_DEBUG")]
        internal static void PRECONDITION(bool condition)
        {
            Assert(condition); 
        }
 
        [Conditional("_DEBUG")] 
        internal static void PRECONDITION(bool condition, string message)
        { 
            Assert(condition, message);
        }

        [Conditional("_DEBUG")] 
        internal static void PRECONDITION(bool condition, string message, string detailedMessage)
        { 
            Assert(condition, message, detailedMessage); 
        }
        #endregion 

        #region POSTCONDITION
        [Conditional("_DEBUG")]
        internal static void POSTCONDITION(bool condition) 
        {
            Assert(condition); 
        } 

        [Conditional("_DEBUG")] 
        internal static void POSTCONDITION(bool condition, string message)
        {
            Assert(condition, message);
        } 

        [Conditional("_DEBUG")] 
        internal static void POSTCONDITION(bool condition, string message, string detailedMessage) 
        {
            Assert(condition, message, detailedMessage); 
        }
        #endregion

        #region CONSISTENCY_CHECK 
        [Conditional("_DEBUG")]
        internal static void CONSISTENCY_CHECK(bool condition) 
        { 
            Assert(condition);
        } 

        [Conditional("_DEBUG")]
        internal static void CONSISTENCY_CHECK(bool condition, string message)
        { 
            Assert(condition, message);
        } 
 
        [Conditional("_DEBUG")]
        internal static void CONSISTENCY_CHECK(bool condition, string message, string detailedMessage) 
        {
            Assert(condition, message, detailedMessage);
        }
        #endregion 

        #region SIMPLIFYING_ASSUMPTION 
        [Conditional("_DEBUG")] 
        internal static void SIMPLIFYING_ASSUMPTION(bool condition)
        { 
            Assert(condition);
        }

        [Conditional("_DEBUG")] 
        internal static void SIMPLIFYING_ASSUMPTION(bool condition, string message)
        { 
            Assert(condition, message); 
        }
 
        [Conditional("_DEBUG")]
        internal static void SIMPLIFYING_ASSUMPTION(bool condition, string message, string detailedMessage)
        {
            Assert(condition, message, detailedMessage); 
        }
        #endregion 
 
        #region UNREACHABLE
        [Conditional("_DEBUG")] 
        internal static void UNREACHABLE()
        {
            Assert();
        } 

        [Conditional("_DEBUG")] 
        internal static void UNREACHABLE(string message) 
        {
            Assert(message); 
        }

        [Conditional("_DEBUG")]
        internal static void UNREACHABLE(string message, string detailedMessage) 
        {
            Assert(message, detailedMessage); 
        } 
        #endregion
 
        #region NOT_IMPLEMENTED
        [Conditional("_DEBUG")]
        internal static void NOT_IMPLEMENTED()
        { 
            Assert();
        } 
 
        [Conditional("_DEBUG")]
        internal static void NOT_IMPLEMENTED(string message) 
        {
            Assert(message);
        }
 
        [Conditional("_DEBUG")]
        internal static void NOT_IMPLEMENTED(string message, string detailedMessage) 
        { 
            Assert(message, detailedMessage);
        } 
        #endregion

        #region Private Asserts - Throw before assert so debugger can inspect
        private static void Assert() 
        {
            Assert(false, null, null); 
        } 

        private static void Assert(string message) 
        {
            Assert(false, message, null);
        }
 
        private static void Assert(bool condition)
        { 
            Assert(condition, null, null); 
        }
 
        private static void Assert(bool condition, string message)
        {
            Assert(condition, message, null);
        } 

        private static void Assert(string message, string detailedMessage) 
        { 
            Assert(false, message, detailedMessage);
        } 

        private static void Assert(bool condition, string message, string detailedMessage)
        {
            if (!condition) 
            {
//                Console.WriteLine("ASSERT MESSAGE: " + message + ", " + detailedMessage); 
//                System.Diagnostics.Debug.Assert(condition, message, detailedMessage); 
//                throw new ASSERT();
            } 
        }
        #endregion
    }
    internal static class LOGIC 
    {
        internal static bool IMPLIES(bool p, bool q) 
        { 
            return !p || q;
        } 

        internal static bool BIJECTION(bool p, bool q)
        {
            return IMPLIES(p,q) && IMPLIES(q,p); 
        }
    } 
    #endregion 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 

 
using System; 
using System.Reflection;
using System.Runtime.ConstrainedExecution; 
using System.Globalization;
using System.Threading;
using System.Diagnostics;
using System.Security.Permissions; 
using System.Collections;
using System.Collections.Generic; 
using System.Runtime.Serialization; 
using System.Runtime.CompilerServices;
using System.Security; 
using System.Text;
using System.Reflection.Emit;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Proxies; 
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Activation; 
using MdSigCallingConvention = System.Signature.MdSigCallingConvention; 
using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
using System.Runtime.InteropServices; 
using DebuggerStepThroughAttribute = System.Diagnostics.DebuggerStepThroughAttribute;
using MdToken = System.Reflection.MetadataToken;

namespace System 
{
    // this is a work around to get the concept of a calli. It's not as fast but it would be interesting to 
    // see how it compares to the current implementation. 
    // This delegate will disappear at some point in favor of calli
 
    internal delegate void CtorDelegate(Object instance);

    [Serializable()]
    internal class RuntimeType : Type, ISerializable, ICloneable 
    {
        #region Definitions 
 
        [Serializable()]
        internal class RuntimeTypeCache 
        {
            #region Definitions
            internal enum WhatsCached
            { 
                Nothing         = 0x0,
                EnclosingType   = 0x1, 
            } 

            internal enum CacheType 
            {
                Method,
                Constructor,
                Field, 
                Property,
                Event, 
                Interface, 
                NestedType
            } 

            // This method serves two purposes, both enabling optimizations in ngen image
            // First, it tells ngen which instantiations of MemberInfoCache to save in the ngen image
            // Second, it ensures MemberInfoCache<*Info>.Insert methods are pre-prepared in the 
            // ngen image, and any runtime preparation that needs to happen, happens in the Prestub
            // worker of Prejitinit_Hack. At runtime we do not really want to execute the Insert methods 
            // here; the calls are present just to fool the CER preparation code into preparing those methods during ngen 
            internal static void Prejitinit_HACK()
            { 
                // make sure this conditional is around everything _including_ the call to
                // PrepareConstrainedRegions, the JIT/NGen just needs to see the callsite
                // somewhere, but the callsite has a link demand which can trip up partially
                // trusted code. 
                if (!s_dontrunhack)
                { 
                    RuntimeHelpers.PrepareConstrainedRegions(); 
                    try
                    { } 
                    finally
                    {
                            MemberInfoCache micrmi = new MemberInfoCache(null);
                            CerArrayList list =null; 
                            micrmi.Insert(ref list, "dummy", MemberListType.All);
 
                            MemberInfoCache micrci = new MemberInfoCache(null); 
                            CerArrayList listc =null;
                            micrci.Insert(ref listc, "dummy", MemberListType.All); 

                            MemberInfoCache micrfi = new MemberInfoCache(null);
                            CerArrayList listf =null;
                            micrfi.Insert(ref listf, "dummy", MemberListType.All); 

                            MemberInfoCache micri = new MemberInfoCache(null); 
                            CerArrayList listi =null; 
                            micri.Insert(ref listi, "dummy", MemberListType.All);
 
                            MemberInfoCache micrpi = new MemberInfoCache(null);
                            CerArrayList listp =null;
                            micrpi.Insert(ref listp, "dummy", MemberListType.All);
 
                            MemberInfoCache micrei = new MemberInfoCache(null);
                            CerArrayList liste =null; 
                            micrei.Insert(ref liste, "dummy", MemberListType.All); 
                    }
                } 
            }

            private struct Filter
            { 
                private Utf8String m_name;
                private MemberListType m_listType; 
 
                public unsafe Filter(byte* pUtf8Name, int cUtf8Name, MemberListType listType)
                { 
                      this.m_name = new Utf8String((void*) pUtf8Name, cUtf8Name);
                      this.m_listType = listType;
                }
 
                public bool Match(Utf8String name)
                { 
                    if (m_listType == MemberListType.CaseSensitive) 
                        return m_name.Equals(name);
                    else if (m_listType == MemberListType.CaseInsensitive) 
                        return m_name.EqualsCaseInsensitive(name);
                    else
                        return true;
                } 
            }
 
            [Serializable()] 
            private class MemberInfoCache where T : MemberInfo
            { 
                #region Static Members

                static MemberInfoCache()
                { 
                    // We need to prepare some code in this class for reliable
                    // execution on a per-instantiation basis. A static class 
                    // constructor is ideal for this since we only need to do 
                    // this once per-instantiation. We can't go through the
                    // normal approach using RuntimeHelpers.PrepareMethod since 
                    // that would involve using reflection and we'd wind back up
                    // here recursively. So we call through an fcall helper
                    // instead. The fcall is on RuntimeType to avoid having an
                    // fcall entry for a nested class (a generic one at that). 
                    // I've no idea if that would work, but I'm pretty sure it
                    // wouldn't. Also we pass in our own base type since using 
                    // the mscorlib binder doesn't work for nested types (I've 
                    // tried that one).
                    PrepareMemberInfoCache(typeof(MemberInfoCache).TypeHandle); 
                }

                #endregion
 
                #region Private Data Members
                // MemberInfo caches 
                private CerHashtable> m_csMemberInfos; 
                private CerHashtable> m_cisMemberInfos;
                private CerArrayList m_root; 
                private bool m_cacheComplete;

                // This is the strong reference back to the cache
                private RuntimeTypeCache m_runtimeTypeCache; 
                #endregion
 
                #region Constructor 
                internal MemberInfoCache(RuntimeTypeCache runtimeTypeCache)
                { 
#if MDA_SUPPORTED
                    Mda.MemberInfoCacheCreation();
#endif
                    m_runtimeTypeCache = runtimeTypeCache; 
                    m_cacheComplete = false;
                } 
 
                internal MethodBase AddMethod(RuntimeTypeHandle declaringType, RuntimeMethodHandle method, CacheType cacheType)
                { 
                    Object list = null;
                    MethodAttributes methodAttributes = method.GetAttributes();
                    bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
                    bool isStatic = (methodAttributes & MethodAttributes.Static) != 0; 
                    bool isInherited = declaringType.Value != ReflectedTypeHandle.Value;
                    BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic); 
                    switch (cacheType) 
                    {
                        case CacheType.Method: 
                            List mlist = new List(1);
                            mlist.Add(new RuntimeMethodInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags));
                            list = mlist;
                            break; 
                        case CacheType.Constructor:
                            List clist = new List(1); 
                            clist.Add(new RuntimeConstructorInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags)); 
                            list = clist;
                            break; 
                    }

                    CerArrayList cerList = new CerArrayList((List)list);
 
                    Insert(ref cerList, null, MemberListType.HandleToInfo);
 
                    return (MethodBase)(object)cerList[0]; 
                }
 
                internal FieldInfo AddField(RuntimeFieldHandle field)
                {
                    // create the runtime field info
                    List list = new List(1); 
                    FieldAttributes fieldAttributes = field.GetAttributes();
                    bool isPublic = (fieldAttributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public; 
                    bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0; 
                    bool isInherited = field.GetApproxDeclaringType().Value != ReflectedTypeHandle.Value;
                    BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic); 
                    list.Add(new RtFieldInfo(field, ReflectedType, m_runtimeTypeCache, bindingFlags));

                    CerArrayList cerList = new CerArrayList((List)(object)list);
                    Insert(ref cerList, null, MemberListType.HandleToInfo); 

                    return (FieldInfo)(object)cerList[0]; 
                } 

                private unsafe CerArrayList Populate(string name, MemberListType listType, CacheType cacheType) 
                {
                    if (name == null || name.Length == 0 ||
                        (cacheType == CacheType.Constructor && name.FirstChar != '.' && name.FirstChar != '*'))
                    { 
                        Filter filter = new Filter(null, 0, listType);
                        List list = null; 
 
                        switch (cacheType)
                        { 
                            case CacheType.Method:
                                list = PopulateMethods(filter) as List;
                                break;
                            case CacheType.Field : 
                                list = PopulateFields(filter) as List;
                                break; 
                            case CacheType.Constructor : 
                                list = PopulateConstructors(filter) as List;
                                break; 
                            case CacheType.Property :
                                list = PopulateProperties(filter) as List;
                                break;
                            case CacheType.Event : 
                                list = PopulateEvents(filter) as List;
                                break; 
                            case CacheType.NestedType : 
                                list = PopulateNestedClasses(filter) as List;
                                break; 
                            case CacheType.Interface :
                                list = PopulateInterfaces(filter) as List;
                                break;
                        } 

                        CerArrayList cerList = new CerArrayList(list); 
 
                        Insert(ref cerList, name, listType);
 
                        return cerList;
                    }
                    else
                    { 
                        fixed (char* pName = name)
                        { 
                            int cUtf8Name = Encoding.UTF8.GetByteCount(pName, name.Length); 
                            byte* pUtf8Name = stackalloc byte[cUtf8Name];
                            Encoding.UTF8.GetBytes(pName, name.Length, pUtf8Name, cUtf8Name); 

                            Filter filter = new Filter(pUtf8Name, cUtf8Name, listType);
                            List list = null;
 
                            switch (cacheType)
                            { 
                                case CacheType.Method: 
                                    list = PopulateMethods(filter) as List;
                                    break; 
                                case CacheType.Field :
                                    list = PopulateFields(filter) as List;
                                    break;
                                case CacheType.Constructor : 
                                    list = PopulateConstructors(filter) as List;
                                    break; 
                                case CacheType.Property : 
                                    list = PopulateProperties(filter) as List;
                                    break; 
                                case CacheType.Event :
                                    list = PopulateEvents(filter) as List;
                                    break;
                                case CacheType.NestedType : 
                                    list = PopulateNestedClasses(filter) as List;
                                    break; 
                                case CacheType.Interface : 
                                    list = PopulateInterfaces(filter) as List;
                                    break; 
                            }

                            CerArrayList cerList = new CerArrayList(list);
 
                            Insert(ref cerList, name, listType);
 
                            return cerList; 
                        }
                    } 
                }

                // May replace the list with a new one if certain cache
                // lookups succeed.  Also, may modify the contents of the list 
                // after merging these new data structures with cached ones.
                [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
                internal void Insert(ref CerArrayList list, string name, MemberListType listType) 
                {
                    bool lockTaken = false; 
                    bool preallocationComplete = false;

                    RuntimeHelpers.PrepareConstrainedRegions();
                    try 
                    {
                        Monitor.ReliableEnter(this, ref lockTaken); 
 
                        if (listType == MemberListType.CaseSensitive)
                        { 
                            if (m_csMemberInfos == null)
                                m_csMemberInfos = new CerHashtable>();
                            else
                                m_csMemberInfos.Preallocate(1); 
                        }
                        else if (listType == MemberListType.CaseInsensitive) 
                        { 
                            if (m_cisMemberInfos == null)
                                m_cisMemberInfos = new CerHashtable>(); 
                            else
                                m_cisMemberInfos.Preallocate(1);
                        }
 
                        if (m_root == null)
                            m_root = new CerArrayList(list.Count); 
                        else 
                            m_root.Preallocate(list.Count);
 
                        preallocationComplete = true;
                    }
                    finally
                    { 
                        try
                        { 
                            if (preallocationComplete) 
                            {
                                if (listType == MemberListType.CaseSensitive) 
                                {
                                    // Ensure we always return a list that has
                                    // been merged with the global list.
                                    CerArrayList cachedList = m_csMemberInfos[name]; 
                                    if (cachedList == null)
                                    { 
                                        MergeWithGlobalList(list); 
                                        m_csMemberInfos[name] = list;
                                    } 
                                    else
                                        list = cachedList;
                                }
                                else if (listType == MemberListType.CaseInsensitive) 
                                {
                                    // Ensure we always return a list that has 
                                    // been merged with the global list. 
                                    CerArrayList cachedList = m_cisMemberInfos[name];
                                    if (cachedList == null) 
                                    {
                                        MergeWithGlobalList(list);
                                        m_cisMemberInfos[name] = list;
                                    } 
                                    else
                                        list = cachedList; 
                                } 
                                else
                                { 
                                    MergeWithGlobalList(list);
                                }

                                if (listType == MemberListType.All) 
                                {
                                    m_cacheComplete = true; 
                                } 
                            }
                        } 
                        finally
                        {
                            if (lockTaken)
                            { 
                                Monitor.Exit(this);
                            } 
                        } 
                    }
                } 

                // Modifies the existing list.
                [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
                private void MergeWithGlobalList(CerArrayList list) 
                {
                    int cachedCount = m_root.Count; 
 
                    for (int i = 0; i < list.Count; i++)
                    { 
                        T newMemberInfo = list[i];
                        T cachedMemberInfo = null;

                        for (int j = 0; j < cachedCount; j++) 
                        {
                            cachedMemberInfo = m_root[j]; 
 
                            if (newMemberInfo.CacheEquals(cachedMemberInfo))
                            { 
                                list.Replace(i, cachedMemberInfo);
                                break;
                            }
                        } 

                        if (list[i] != cachedMemberInfo) 
                            m_root.Add(newMemberInfo); 
                    }
                } 
                #endregion

                #region Population Logic
                private unsafe List PopulateMethods(Filter filter) 
                {
                    List list = new List(); 
 
                    RuntimeTypeHandle declaringTypeHandle = ReflectedTypeHandle;
 
                    bool isInterface =
                        (declaringTypeHandle.GetAttributes() & TypeAttributes.ClassSemanticsMask)
                        == TypeAttributes.Interface;
 
                    if (isInterface)
                    { 
                        #region IsInterface 
                        bool mayNeedInstantiatingStub = declaringTypeHandle.HasInstantiation() && !declaringTypeHandle.IsGenericTypeDefinition();
 
                        foreach (RuntimeMethodHandle methodHandle in declaringTypeHandle.IntroducedMethods)
                        {
                            if (!filter.Match(methodHandle.GetUtf8Name()))
                                continue; 

                            #region Loop through all methods on the interface 
                            ASSERT.CONSISTENCY_CHECK(!methodHandle.IsNullHandle()); 
                            ASSERT.CONSISTENCY_CHECK(LOGIC.IMPLIES(
                                (methodHandle.GetAttributes() & MethodAttributes.RTSpecialName) != 0, 
                                methodHandle.GetName().Equals(".ctor") ||
                                methodHandle.GetName().Equals(".cctor") ||
                                methodHandle.GetName().Equals("IL_STUB")));
                            ASSERT.CONSISTENCY_CHECK((methodHandle.GetAttributes() & MethodAttributes.Abstract) != 0); 
                            ASSERT.CONSISTENCY_CHECK((methodHandle.GetAttributes() & MethodAttributes.Virtual) != 0);
 
                            #region Calculate Binding Flags 
                            MethodAttributes methodAttributes = methodHandle.GetAttributes();
                            bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public; 
                            bool isStatic = (methodAttributes & MethodAttributes.Static) != 0;
                            bool isInherited = false;
                            BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
                            #endregion 

                            if ((methodAttributes & MethodAttributes.RTSpecialName) != 0 || methodHandle.IsILStub()) 
                                continue; 

                            // if it is an instantiated type get the InstantiatedMethodDesc if needed 
                            RuntimeMethodHandle instantiatedHandle = mayNeedInstantiatingStub ?
                                methodHandle.GetInstantiatingStubIfNeeded(declaringTypeHandle) : methodHandle;

                            RuntimeMethodInfo runtimeMethodInfo = new RuntimeMethodInfo( 
                                instantiatedHandle, declaringTypeHandle, m_runtimeTypeCache, methodAttributes, bindingFlags);
 
                            list.Add(runtimeMethodInfo); 
                            #endregion
                        } 
                        #endregion
                    }
                    else
                    { 
                        #region IsClass or GenericParameter
                        while(declaringTypeHandle.IsGenericVariable()) 
                            declaringTypeHandle = declaringTypeHandle.GetRuntimeType().BaseType.GetTypeHandleInternal(); 

                        bool* overrides = stackalloc bool[declaringTypeHandle.GetNumVirtuals()]; 
                        bool isValueType = declaringTypeHandle.GetRuntimeType().IsValueType;

                        while(!declaringTypeHandle.IsNullHandle())
                        { 
                            bool mayNeedInstantiatingStub = declaringTypeHandle.HasInstantiation() &&
                                !declaringTypeHandle.IsGenericTypeDefinition(); 
 
                            int vtableSlots = declaringTypeHandle.GetNumVirtuals();
 
                            foreach (RuntimeMethodHandle methodHandle in declaringTypeHandle.IntroducedMethods)
                            {
                                if (!filter.Match(methodHandle.GetUtf8Name()))
                                    continue; 

                                #region Loop through all methods on the current type 
                                ASSERT.CONSISTENCY_CHECK(!methodHandle.IsNullHandle()); 

                                MethodAttributes methodAttributes = methodHandle.GetAttributes(); 
                                MethodAttributes methodAccess = methodAttributes & MethodAttributes.MemberAccessMask;

                                #region Continue if this is a constructor
                                ASSERT.CONSISTENCY_CHECK( 
                                    LOGIC.IMPLIES((methodHandle.GetAttributes() & MethodAttributes.RTSpecialName) != 0,
                                    methodHandle.GetName().Equals(".ctor") || 
                                    methodHandle.GetName().Equals(".cctor") || 
                                    methodHandle.GetName().Equals("IL_STUB") ));
 
                                if ((methodAttributes & MethodAttributes.RTSpecialName) != 0 || methodHandle.IsILStub())
                                    continue;
                                #endregion
 
                                #region Continue if this is a private declared on a base type
                                bool isVirtual = false; 
                                int methodSlot = 0; 
                                if ((methodAttributes & MethodAttributes.Virtual) != 0)
                                { 
                                    // only virtual if actually in the vtableslot range, but GetSlot will
                                    // assert if an EnC method, which can't be virtual, so narrow down first
                                    // before calling GetSlot
                                    methodSlot = methodHandle.GetSlot(); 
                                    isVirtual = (methodSlot < vtableSlots);
                                } 
                                bool isPrivate = methodAccess == MethodAttributes.Private; 
                                bool isPrivateVirtual = isVirtual & isPrivate;
                                bool isInherited = declaringTypeHandle.Value != ReflectedTypeHandle.Value; 
                                if (isInherited && isPrivate && !isPrivateVirtual)
                                    continue;
                                #endregion
 
                                #region Continue if this is a virtual and is already overridden
                                if (isVirtual) 
                                { 
                                    ASSERT.CONSISTENCY_CHECK(
                                        (methodAttributes & MethodAttributes.Abstract) != 0 || 
                                        (methodAttributes & MethodAttributes.Virtual) != 0 ||
                                        methodHandle.GetDeclaringType().Value != declaringTypeHandle.Value);

                                    if (overrides[methodSlot] == true) 
                                        continue;
 
                                    overrides[methodSlot] = true; 
                                }
                                else if (isValueType) 
                                {
                                    if ((methodAttributes & (MethodAttributes.Virtual | MethodAttributes.Abstract)) != 0)
                                        continue;
                                } 
                                else
                                { 
                                    ASSERT.CONSISTENCY_CHECK((methodAttributes & (MethodAttributes.Virtual | MethodAttributes.Abstract)) == 0); 
                                }
                                #endregion 

                                #region Calculate Binding Flags
                                bool isPublic = methodAccess == MethodAttributes.Public;
                                bool isStatic = (methodAttributes & MethodAttributes.Static) != 0; 
                                BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
                                #endregion 
 
                                // if it is an instantiated type get the InstantiatedMethodDesc if needed
                                RuntimeMethodHandle instantiatedHandle = mayNeedInstantiatingStub ? 
                                    methodHandle.GetInstantiatingStubIfNeeded(declaringTypeHandle) : methodHandle;

                                RuntimeMethodInfo runtimeMethodInfo = new RuntimeMethodInfo(
                                    instantiatedHandle, declaringTypeHandle, m_runtimeTypeCache, methodAttributes, bindingFlags); 

                                list.Add(runtimeMethodInfo); 
                                #endregion 
                            }
 
                            declaringTypeHandle = declaringTypeHandle.GetBaseTypeHandle();
                        }
                        #endregion
                    } 

                    return list; 
                } 

                private List PopulateConstructors(Filter filter) 
                {
                    List list = new List();

                    if (ReflectedType.IsGenericParameter) 
                    {
                        return list; 
                    } 

                    RuntimeTypeHandle declaringTypeHandle = ReflectedTypeHandle; 

                    bool mayNeedInstantiatingStub = declaringTypeHandle.HasInstantiation() &&
                        !declaringTypeHandle.IsGenericTypeDefinition();
 
                    foreach (RuntimeMethodHandle methodHandle in declaringTypeHandle.IntroducedMethods)
                    { 
                        if (!filter.Match(methodHandle.GetUtf8Name())) 
                            continue;
 
                        MethodAttributes methodAttributes = methodHandle.GetAttributes();

                        ASSERT.CONSISTENCY_CHECK(!methodHandle.IsNullHandle());
/* 
                        ASSERT.CONSISTENCY_
 
 

 
*/

                        if ((methodAttributes & MethodAttributes.RTSpecialName) == 0)
                            continue; 

                        if (methodHandle.IsILStub()) 
                            continue; 

                        // Constructors should not be virtual or abstract 
                        ASSERT.CONSISTENCY_CHECK(
                            (methodAttributes & MethodAttributes.Abstract) == 0 &&
                            (methodAttributes & MethodAttributes.Virtual) == 0);
 
                        #region Calculate Binding Flags
                        bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public; 
                        bool isStatic = (methodAttributes & MethodAttributes.Static) != 0; 
                        bool isInherited = false;
                        BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic); 
                        #endregion

                        // if it is an instantiated type get the InstantiatedMethodDesc if needed
                        RuntimeMethodHandle instantiatedHandle = mayNeedInstantiatingStub ? 
                            methodHandle.GetInstantiatingStubIfNeeded(declaringTypeHandle) : methodHandle;
 
                        RuntimeConstructorInfo runtimeConstructorInfo = 
                            new RuntimeConstructorInfo(instantiatedHandle, ReflectedTypeHandle, m_runtimeTypeCache, methodAttributes, bindingFlags);
 
                        list.Add(runtimeConstructorInfo);
                    }

                    return list; 
                }
 
                private unsafe List PopulateFields(Filter filter) 
                {
                    List list = new List(); 

                    RuntimeTypeHandle declaringTypeHandle = ReflectedTypeHandle;

                    #region Populate all static, instance and literal fields 
                    while(declaringTypeHandle.IsGenericVariable())
                        declaringTypeHandle = declaringTypeHandle.GetRuntimeType().BaseType.GetTypeHandleInternal(); 
 
                    while(!declaringTypeHandle.IsNullHandle())
                    { 
                        PopulateRtFields(filter, declaringTypeHandle, list);

                        PopulateLiteralFields(filter, declaringTypeHandle, list);
 
                        declaringTypeHandle = declaringTypeHandle.GetBaseTypeHandle();
                    } 
                    #endregion 

                    #region Populate Literal Fields on Interfaces 
                    if (ReflectedType.IsGenericParameter)
                    {
                        Type[] interfaces = ReflectedTypeHandle.GetRuntimeType().BaseType.GetInterfaces();
 
                        for (int i = 0; i < interfaces.Length; i++)
                        { 
                            // Populate literal fields defined on any of the interfaces implemented by the declaring type 
                            PopulateLiteralFields(filter, interfaces[i].GetTypeHandleInternal(), list);
                            PopulateRtFields(filter, interfaces[i].GetTypeHandleInternal(), list); 
                        }
                    }
                    else
                    { 
                        RuntimeTypeHandle[] interfaces = ReflectedTypeHandle.GetInterfaces();
 
                        if (interfaces != null) 
                        {
                            for (int i = 0; i < interfaces.Length; i++) 
                            {
                                // Populate literal fields defined on any of the interfaces implemented by the declaring type
                                PopulateLiteralFields(filter, interfaces[i], list);
                                PopulateRtFields(filter, interfaces[i], list); 
                            }
                        } 
                    } 
                    #endregion
 
                    return list;
                }

                private unsafe void PopulateRtFields(Filter filter, RuntimeTypeHandle declaringTypeHandle, List list) 
                {
                    int** pResult = stackalloc int*[64]; 
                    int count = 64; 

                    if (!declaringTypeHandle.GetFields(pResult, &count)) 
                    {
                        fixed(int** pBigResult = new int*[count])
                        {
                            declaringTypeHandle.GetFields(pBigResult, &count); 
                            PopulateRtFields(filter, pBigResult, count, declaringTypeHandle, list);
                        } 
                    } 
                    else if (count > 0)
                    { 
                        PopulateRtFields(filter, pResult, count, declaringTypeHandle, list);
                    }
                }
 
                private unsafe void PopulateRtFields(Filter filter,
                    int** ppFieldHandles, int count, RuntimeTypeHandle declaringTypeHandle, List list) 
                { 
                    ASSERT.PRECONDITION(!declaringTypeHandle.IsNullHandle());
                    ASSERT.PRECONDITION(!ReflectedTypeHandle.IsNullHandle()); 

                    bool needsStaticFieldForGeneric = declaringTypeHandle.HasInstantiation() && !declaringTypeHandle.ContainsGenericVariables();
                    bool isInherited = !declaringTypeHandle.Equals(ReflectedTypeHandle);
 
                    for(int i = 0; i < count; i ++)
                    { 
                        RuntimeFieldHandle runtimeFieldHandle = new RuntimeFieldHandle(ppFieldHandles[i]); 

                        if (!filter.Match(runtimeFieldHandle.GetUtf8Name())) 
                            continue;

                        ASSERT.CONSISTENCY_CHECK(!runtimeFieldHandle.IsNullHandle());
 
                        FieldAttributes fieldAttributes = runtimeFieldHandle.GetAttributes();
                        FieldAttributes fieldAccess = fieldAttributes & FieldAttributes.FieldAccessMask; 
 
                        if (isInherited)
                        { 
                            if (fieldAccess == FieldAttributes.Private)
                                continue;
                        }
 
                        #region Calculate Binding Flags
                        bool isPublic = fieldAccess == FieldAttributes.Public; 
                        bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0; 
                        BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
                        #endregion 

                        // correct the FieldDesc if needed
                        if (needsStaticFieldForGeneric && isStatic)
                            runtimeFieldHandle = runtimeFieldHandle.GetStaticFieldForGenericType(declaringTypeHandle); 

                        RuntimeFieldInfo runtimeFieldInfo = 
                            new RtFieldInfo(runtimeFieldHandle, declaringTypeHandle.GetRuntimeType(), m_runtimeTypeCache, bindingFlags); 

                        list.Add(runtimeFieldInfo); 
                    }
                }

                private unsafe void PopulateLiteralFields(Filter filter, RuntimeTypeHandle declaringTypeHandle, List list) 
                {
                    ASSERT.PRECONDITION(!declaringTypeHandle.IsNullHandle()); 
                    ASSERT.PRECONDITION(!ReflectedTypeHandle.IsNullHandle()); 

                    int tkDeclaringType = declaringTypeHandle.GetToken(); 

                    // Our policy is that TypeDescs do not have metadata tokens
                    if (MdToken.IsNullToken(tkDeclaringType))
                        return; 

                    MetadataImport scope = declaringTypeHandle.GetModuleHandle().GetMetadataImport(); 
                    int cFields = scope.EnumFieldsCount(tkDeclaringType); 
                    int* tkFields = stackalloc int[cFields];
                    scope.EnumFields(tkDeclaringType, tkFields, cFields); 

                    for (int i = 0; i < cFields; i++)
                    {
                        int tkField = tkFields[i]; 
                        ASSERT.PRECONDITION(MdToken.IsTokenOfType(tkField, MetadataTokenType.FieldDef));
                        ASSERT.PRECONDITION(!MdToken.IsNullToken(tkField)); 
 
                        Utf8String name;
                        name = scope.GetName(tkField); 

                        if (!filter.Match(name))
                            continue;
 
                        FieldAttributes fieldAttributes;
                        scope.GetFieldDefProps(tkField, out fieldAttributes); 
 
                        FieldAttributes fieldAccess = fieldAttributes & FieldAttributes.FieldAccessMask;
 
                        if ((fieldAttributes & FieldAttributes.Literal) != 0)
                        {
                            bool isInherited = !declaringTypeHandle.Equals(ReflectedTypeHandle);
                            if (isInherited) 
                            {
                                bool isPrivate = fieldAccess == FieldAttributes.Private; 
                                if (isPrivate) 
                                    continue;
                            } 

                            #region Calculate Binding Flags
                            bool isPublic = fieldAccess == FieldAttributes.Public;
                            bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0; 
                            BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
                            #endregion 
 
                            RuntimeFieldInfo runtimeFieldInfo =
                            new MdFieldInfo(tkField, fieldAttributes, declaringTypeHandle, m_runtimeTypeCache, bindingFlags); 

                            list.Add(runtimeFieldInfo);
                        }
                    } 
                }
 
                private static void AddElementTypes(Type template, IList types) 
                {
                    if (!template.HasElementType) 
                        return;

                    AddElementTypes(template.GetElementType(), types);
 
                    for (int i = 0; i < types.Count; i ++)
                    { 
                        if (template.IsArray) 
                        {
                            if (template.IsSzArray) 
                                types[i] = types[i].MakeArrayType();
                            else
                                types[i] = types[i].MakeArrayType(template.GetArrayRank());
                        } 
                        else if (template.IsPointer)
                        { 
                            types[i] = types[i].MakePointerType(); 
                        }
                    } 
                }

                private List PopulateInterfaces(Filter filter)
                { 
                    List list = new List();
 
                    RuntimeTypeHandle declaringTypeHandle = ReflectedTypeHandle; 

                    if (!declaringTypeHandle.IsGenericVariable()) 
                    {
                        RuntimeTypeHandle[] ifaces = ReflectedTypeHandle.GetInterfaces();

                        if (ifaces != null) 
                        {
                            for (int i = 0; i < ifaces.Length; i++) 
                            { 
                                RuntimeType interfaceType = ifaces[i].GetRuntimeType();
 
                                if (!filter.Match(interfaceType.GetTypeHandleInternal().GetUtf8Name()))
                                    continue;

                                ASSERT.CONSISTENCY_CHECK(interfaceType.IsInterface); 
                                list.Add(interfaceType);
                            } 
                        } 

                        if (ReflectedType.IsSzArray) 
                        {
                            Type arrayType = ReflectedType.GetElementType();

                            if (!arrayType.IsPointer) 
                            {
                                Type iList = typeof(IList<>).MakeGenericType(arrayType); 
 
                                if (iList.IsAssignableFrom(ReflectedType))
                                { 
                                    if (filter.Match(iList.GetTypeHandleInternal().GetUtf8Name()))
                                        list.Add(iList as RuntimeType);

                                    Type[] iFaces = iList.GetInterfaces(); 
                                    for(int j = 0; j < iFaces.Length; j++)
                                    { 
                                        Type iFace = iFaces[j]; 
                                        if (iFace.IsGenericType && filter.Match(iFace.GetTypeHandleInternal().GetUtf8Name()))
                                            list.Add(iFaces[j] as RuntimeType); 
                                    }
                                }
                            }
                        } 
                    }
                    else 
                    { 
                        List al = new List();
 
                        // Get all constraints
                        Type[] constraints = declaringTypeHandle.GetRuntimeType().GetGenericParameterConstraints();

                        // Populate transitive closure of all interfaces in constraint set 
                        for (int i = 0; i < constraints.Length; i++)
                        { 
                            Type constraint = constraints[i]; 
                            if (constraint.IsInterface)
                                al.Add(constraint as RuntimeType); 

                            Type[] temp = constraint.GetInterfaces();
                            for (int j = 0; j < temp.Length; j++)
                                al.Add(temp[j] as RuntimeType); 
                        }
 
                        // Remove duplicates 
                        Hashtable ht = new Hashtable();
                        for (int i = 0; i < al.Count; i++) 
                        {
                            Type constraint = al[i] as Type;
                            if (!ht.Contains(constraint))
                                ht[constraint] = constraint; 
                        }
 
                        Type[] interfaces = new Type[ht.Values.Count]; 
                        ht.Values.CopyTo(interfaces, 0);
 
                        // Populate link-list
                        for (int i = 0; i < interfaces.Length; i++)
                        {
                            if (!filter.Match(interfaces[i].GetTypeHandleInternal().GetUtf8Name())) 
                                continue;
 
                            list.Add(interfaces[i] as RuntimeType); 
                        }
                    } 

                    return list;
                }
 
                private unsafe List PopulateNestedClasses(Filter filter)
                { 
                    List list = new List(); 

                    RuntimeTypeHandle declaringTypeHandle = ReflectedTypeHandle; 

                    if (declaringTypeHandle.IsGenericVariable())
                    {
                        while(declaringTypeHandle.IsGenericVariable()) 
                            declaringTypeHandle = declaringTypeHandle.GetRuntimeType().BaseType.GetTypeHandleInternal();
                    } 
 
                    int tkEnclosingType = declaringTypeHandle.GetToken();
 
                    // For example, TypeDescs do not have metadata tokens
                    if (MdToken.IsNullToken(tkEnclosingType))
                        return list;
 
                    ModuleHandle moduleHandle = declaringTypeHandle.GetModuleHandle();
                    MetadataImport scope = moduleHandle.GetMetadataImport(); 
 
                    int cNestedClasses = scope.EnumNestedTypesCount(tkEnclosingType);
                    int* tkNestedClasses = stackalloc int[cNestedClasses]; 
                    scope.EnumNestedTypes(tkEnclosingType, tkNestedClasses, cNestedClasses);

                    for (int i = 0; i < cNestedClasses; i++)
                    { 
                        RuntimeTypeHandle nestedTypeHandle = new RuntimeTypeHandle();
 
                        try 
                        {
                            nestedTypeHandle = moduleHandle.ResolveTypeHandle(tkNestedClasses[i]); 
                        }
                        catch(System.TypeLoadException)
                        {
                            // In a reflection emit scenario, we may have a token for a class which 
                            // has not been baked and hence cannot be loaded.
                            continue; 
                        } 

                        if (!filter.Match(nestedTypeHandle.GetRuntimeType().GetTypeHandleInternal().GetUtf8Name())) 
                            continue;

                        list.Add(nestedTypeHandle.GetRuntimeType());
                    } 

                    return list; 
                } 

                private unsafe List PopulateEvents(Filter filter) 
                {
                    ASSERT.PRECONDITION(!ReflectedTypeHandle.IsNullHandle());

                    Hashtable csEventInfos = new Hashtable(); 

                    RuntimeTypeHandle declaringTypeHandle = ReflectedTypeHandle; 
                    List list = new List(); 

                    bool isInterface = (declaringTypeHandle.GetAttributes() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface; 

                    if (!isInterface)
                    {
                        while(declaringTypeHandle.IsGenericVariable()) 
                            declaringTypeHandle = declaringTypeHandle.GetRuntimeType().BaseType.GetTypeHandleInternal();
 
                        // Populate associates off of the class hierarchy 
                        while(!declaringTypeHandle.IsNullHandle())
                        { 
                            PopulateEvents(filter, declaringTypeHandle, csEventInfos, list);
                            declaringTypeHandle = declaringTypeHandle.GetBaseTypeHandle();
                        }
                    } 
                    else
                    { 
                        // Populate associates for this interface 
                        PopulateEvents(filter, declaringTypeHandle, csEventInfos, list);
                    } 

                    return list;
                }
 
                private unsafe void PopulateEvents(
                    Filter filter, RuntimeTypeHandle declaringTypeHandle, Hashtable csEventInfos, List list) 
                { 
                    int tkDeclaringType = declaringTypeHandle.GetToken();
 
                    // Arrays, Pointers, ByRef types and others generated only the fly by the RT do not have tokens.
                    if (MdToken.IsNullToken(tkDeclaringType))
                        return;
 
                    MetadataImport scope = declaringTypeHandle.GetModuleHandle().GetMetadataImport();
                    int cEvents = scope.EnumEventsCount(tkDeclaringType); 
                    int* tkEvents = stackalloc int[cEvents]; 
                    scope.EnumEvents(tkDeclaringType, tkEvents, cEvents);
                    PopulateEvents(filter, declaringTypeHandle, scope, tkEvents, cEvents, csEventInfos, list); 
                }

                private unsafe void PopulateEvents(Filter filter,
                    RuntimeTypeHandle declaringTypeHandle, MetadataImport scope, int* tkAssociates, int cAssociates, Hashtable csEventInfos, List list) 
                {
                    for (int i = 0; i < cAssociates; i++) 
                    { 
                        int tkAssociate = tkAssociates[i];
                        bool isPrivate; 

                        ASSERT.PRECONDITION(!MdToken.IsNullToken(tkAssociate));
                        ASSERT.PRECONDITION(MdToken.IsTokenOfType(tkAssociate, MetadataTokenType.Event));
 
                        Utf8String name;
                        name = scope.GetName(tkAssociate); 
 
                        if (!filter.Match(name))
                            continue; 

                        RuntimeEventInfo eventInfo = new RuntimeEventInfo(
                            tkAssociate, declaringTypeHandle.GetRuntimeType() as RuntimeType, m_runtimeTypeCache, out isPrivate);
 
                        #region Remove Inherited Privates
                        if (!declaringTypeHandle.Equals(m_runtimeTypeCache.RuntimeTypeHandle) && isPrivate) 
                            continue; 
                        #endregion
 
                        #region Remove Duplicates
                        if (csEventInfos[eventInfo.Name] != null)
                            continue;
 
                        csEventInfos[eventInfo.Name] = eventInfo;
                        #endregion 
 
                        list.Add(eventInfo);
                    } 
                }

                private unsafe List PopulateProperties(Filter filter)
                { 
                    ASSERT.PRECONDITION(!ReflectedTypeHandle.IsNullHandle());
                    ASSERT.CONSISTENCY_CHECK(m_csMemberInfos == null); 
 
                    Hashtable csPropertyInfos = new Hashtable();
 
                    RuntimeTypeHandle declaringTypeHandle = ReflectedTypeHandle;
                    List list = new List();

                    bool isInterface = (declaringTypeHandle.GetAttributes() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface; 

                    if (!isInterface) 
                    { 
                        while(declaringTypeHandle.IsGenericVariable())
                            declaringTypeHandle = declaringTypeHandle.GetRuntimeType().BaseType.GetTypeHandleInternal(); 

                        // Populate associates off of the class hierarchy
                        while(!declaringTypeHandle.IsNullHandle())
                        { 
                            PopulateProperties(filter, declaringTypeHandle, csPropertyInfos, list);
                            declaringTypeHandle = declaringTypeHandle.GetBaseTypeHandle(); 
                        } 
                    }
                    else 
                    {
                        // Populate associates for this interface
                        PopulateProperties(filter, declaringTypeHandle, csPropertyInfos, list);
                    } 

                    return list; 
                } 

                private unsafe void PopulateProperties(Filter filter, 
                    RuntimeTypeHandle declaringTypeHandle, Hashtable csPropertyInfos, List list)
                {
                    int tkDeclaringType = declaringTypeHandle.GetToken();
 
                    // Arrays, Pointers, ByRef types and others generated only the fly by the RT do not have tokens.
                    if (MdToken.IsNullToken(tkDeclaringType)) 
                        return; 

                    MetadataImport scope = declaringTypeHandle.GetModuleHandle().GetMetadataImport(); 
                    int cProperties = scope.EnumPropertiesCount(tkDeclaringType);
                    int* tkProperties = stackalloc int[cProperties];
                    scope.EnumProperties(tkDeclaringType, tkProperties, cProperties);
                    PopulateProperties(filter, declaringTypeHandle, tkProperties, cProperties, csPropertyInfos, list); 
                }
 
                private unsafe void PopulateProperties(Filter filter, 
                    RuntimeTypeHandle declaringTypeHandle, int* tkAssociates, int cProperties, Hashtable csPropertyInfos, List list)
                { 
                    for(int i = 0; i < cProperties; i ++)
                    {
                        int tkAssociate = tkAssociates[i];
                        bool isPrivate; 

                        ASSERT.PRECONDITION(!MdToken.IsNullToken(tkAssociate)); 
                        ASSERT.PRECONDITION(MdToken.IsTokenOfType(tkAssociate, MetadataTokenType.Property)); 

                        Utf8String name; 
                        name = declaringTypeHandle.GetRuntimeType().Module.MetadataImport.GetName(tkAssociate);

                        if (!filter.Match(name))
                            continue; 

                        RuntimePropertyInfo propertyInfo = 
                            new RuntimePropertyInfo( 
                            tkAssociate, declaringTypeHandle.GetRuntimeType() as RuntimeType, m_runtimeTypeCache, out isPrivate);
 
                        #region Remove Privates
                        if (!declaringTypeHandle.Equals(m_runtimeTypeCache.RuntimeTypeHandle) && isPrivate)
                            continue;
                        #endregion 

                        #region Remove Duplicates 
                        List cache = csPropertyInfos[propertyInfo.Name] as List; 

                        if (cache == null) 
                        {
                            cache = new List();
                            csPropertyInfos[propertyInfo.Name] = cache;
                        } 
                        else
                        { 
                            for (int j = 0; j < cache.Count; j ++) 
                            {
                                if (propertyInfo.EqualsSig(cache[j])) 
                                {
                                    cache = null;
                                    break;
                                } 
                            }
                        } 
 
                        if (cache == null)
                            continue; 

                        cache.Add(propertyInfo);
                        #endregion
 
                        list.Add(propertyInfo);
                    } 
                } 
                #endregion
 
                #region NonPrivate Members
                internal CerArrayList GetMemberList(MemberListType listType, string name, CacheType cacheType)
                {
                    CerArrayList list = null; 

                    switch(listType) 
                    { 
                        case MemberListType.CaseSensitive:
                            if (m_csMemberInfos == null) 
                            {
                                return Populate(name, listType, cacheType);
                            }
                            else 
                            {
                                list = m_csMemberInfos[name]; 
 
                                if (list == null)
                                    return Populate(name, listType, cacheType); 

                                return list;
                            }
 
                        case MemberListType.All:
                            if (m_cacheComplete) 
                                return m_root; 

                            return Populate(null, listType, cacheType); 

                        default:
                            if (m_cisMemberInfos == null)
                            { 
                                return Populate(name, listType, cacheType);
                            } 
                            else 
                            {
                                list = m_cisMemberInfos[name]; 

                                if (list == null)
                                    return Populate(name, listType, cacheType);
 
                                return list;
                            } 
                    } 
                }
 
                internal RuntimeTypeHandle ReflectedTypeHandle
                {
                    get
                    { 
                        return m_runtimeTypeCache.RuntimeTypeHandle;
                    } 
                } 
                internal RuntimeType ReflectedType
                { 
                    get
                    {
                        return ReflectedTypeHandle.GetRuntimeType();
                    } 
                }
                #endregion 
            } 
            #endregion
 
            #region Private Data Members
            private WhatsCached m_whatsCached;
            private RuntimeTypeHandle m_runtimeTypeHandle;
            private RuntimeType m_runtimeType; 
            private RuntimeType m_enclosingType;
            private TypeCode m_typeCode; 
            private string m_name, m_fullname, m_toString, m_namespace; 
            private bool m_isGlobal;
            private bool m_bIsDomainInitialized; 
            private MemberInfoCache m_methodInfoCache;
            private MemberInfoCache m_constructorInfoCache;
            private MemberInfoCache m_fieldInfoCache;
            private MemberInfoCache m_interfaceCache; 
            private MemberInfoCache m_nestedClassesCache;
            private MemberInfoCache m_propertyInfoCache; 
            private MemberInfoCache m_eventInfoCache; 
            private static CerHashtable s_methodInstantiations;
            private static bool s_dontrunhack = false; 
            #endregion

            #region Constructor
            internal RuntimeTypeCache(RuntimeType runtimeType) 
            {
                m_typeCode = TypeCode.Empty; 
                m_runtimeType = runtimeType; 
                m_runtimeTypeHandle = runtimeType.GetTypeHandleInternal();
                m_isGlobal = m_runtimeTypeHandle.GetModuleHandle().GetModuleTypeHandle().Equals(m_runtimeTypeHandle); 
                s_dontrunhack = true;
                Prejitinit_HACK();
            }
            #endregion 

            #region Private Members 
            private string ConstructName(ref string name, bool nameSpace, bool fullinst, bool assembly) 
            {
                if (name == null) 
                {
                    name = RuntimeTypeHandle.ConstructName(nameSpace, fullinst, assembly);
                }
                return name; 
            }
 
            private CerArrayList GetMemberList(ref MemberInfoCache m_cache, MemberListType listType, string name, CacheType cacheType) 
                where T : MemberInfo
            { 
                MemberInfoCache existingCache = GetMemberCache(ref m_cache);
                return existingCache.GetMemberList(listType, name, cacheType);
            }
 
            private MemberInfoCache GetMemberCache(ref MemberInfoCache m_cache)
                where T : MemberInfo 
            { 
                MemberInfoCache existingCache = m_cache;
 
                if (existingCache == null)
                {
                    MemberInfoCache newCache = new MemberInfoCache(this);
                    existingCache = Interlocked.CompareExchange(ref m_cache, newCache, null); 
                    if (existingCache == null)
                        existingCache = newCache; 
                } 

                return existingCache; 
            }
            #endregion

            #region Internal Members 
            internal bool DomainInitialized
            { 
                get { return m_bIsDomainInitialized; } 
                set { m_bIsDomainInitialized = value; }
            } 

            internal string GetName()
            {
                return ConstructName(ref m_name, false, false, false); 
            }
 
            internal unsafe string GetNameSpace() 
            {
                // @Optimization - Use ConstructName to populate m_namespace 
                if (m_namespace == null)
                {
                    Type type = m_runtimeType;
                    type = type.GetRootElementType(); 

                    while (type.IsNested) 
                        type = type.DeclaringType; 

                    m_namespace = type.GetTypeHandleInternal().GetModuleHandle( 
                        ).GetMetadataImport().GetNamespace(type.MetadataToken).ToString();
                }

                return m_namespace; 
            }
 
            internal string GetToString() 
            {
                return ConstructName(ref m_toString, true, false, false); 
            }

            internal string GetFullName()
            { 
                if (!m_runtimeType.IsGenericTypeDefinition && m_runtimeType.ContainsGenericParameters)
                    return null; 
 
                return ConstructName(ref m_fullname, true, true, false);
            } 

            internal TypeCode TypeCode
            {
                get { return m_typeCode; } 
                set { m_typeCode = value; }
            } 
 
            internal unsafe RuntimeType GetEnclosingType()
            { 
                if ((m_whatsCached & WhatsCached.EnclosingType) == 0)
                {
                    m_enclosingType = RuntimeTypeHandle.GetDeclaringType().GetRuntimeType();
 
                    m_whatsCached |= WhatsCached.EnclosingType;
                } 
 
                return m_enclosingType;
            } 

            internal bool IsGlobal
            {
                [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
                get { return m_isGlobal; }
            } 
            internal RuntimeType RuntimeType { get { return m_runtimeType; } } 
            internal RuntimeTypeHandle RuntimeTypeHandle
            { 
                get
                {
                    return m_runtimeTypeHandle;
                } 
            }
            internal void InvalidateCachedNestedType() 
            { 
                m_nestedClassesCache = null;
            } 
            #endregion

            #region Caches Accessors
            internal MethodInfo GetGenericMethodInfo(RuntimeMethodHandle genericMethod) 
            {
                if (s_methodInstantiations == null) 
                    Interlocked.CompareExchange(ref s_methodInstantiations, new CerHashtable(), null); 

                RuntimeMethodInfo rmi = new RuntimeMethodInfo( 
                    genericMethod, genericMethod.GetDeclaringType(), this,
                    genericMethod.GetAttributes(), (BindingFlags)(-1));

                RuntimeMethodInfo crmi = null; 

                crmi = s_methodInstantiations[rmi]; 
                if (crmi != null) 
                    return crmi;
 
                bool lockTaken = false;
                bool preallocationComplete = false;
                RuntimeHelpers.PrepareConstrainedRegions();
                try 
                {
                    Monitor.ReliableEnter(s_methodInstantiations, ref lockTaken); 
 
                    crmi = s_methodInstantiations[rmi];
                    if (crmi != null) 
                        return crmi;

                    s_methodInstantiations.Preallocate(1);
 
                    preallocationComplete = true;
                } 
                finally 
                {
                    if (preallocationComplete) 
                    {
                        s_methodInstantiations[rmi] = rmi;
                    }
 
                    if (lockTaken)
                    { 
                        Monitor.Exit(s_methodInstantiations); 
                    }
                } 

                return rmi;
            }
 
            internal CerArrayList GetMethodList(MemberListType listType, string name)
            { 
                return GetMemberList(ref m_methodInfoCache, listType, name, CacheType.Method); 
            }
 
            internal CerArrayList GetConstructorList(MemberListType listType, string name)
            {
                return GetMemberList(ref m_constructorInfoCache, listType, name, CacheType.Constructor);
            } 

            internal CerArrayList GetPropertyList(MemberListType listType, string name) 
            { 
                return GetMemberList(ref m_propertyInfoCache, listType, name, CacheType.Property);
            } 

            internal CerArrayList GetEventList(MemberListType listType, string name)
            {
                return GetMemberList(ref m_eventInfoCache, listType, name, CacheType.Event); 
            }
 
            internal CerArrayList GetFieldList(MemberListType listType, string name) 
            {
                return GetMemberList(ref m_fieldInfoCache, listType, name, CacheType.Field); 
            }

            internal CerArrayList GetInterfaceList(MemberListType listType, string name)
            { 
                return GetMemberList(ref m_interfaceCache, listType, name, CacheType.Interface);
            } 
 
            internal CerArrayList GetNestedTypeList(MemberListType listType, string name)
            { 
                return GetMemberList(ref m_nestedClassesCache, listType, name, CacheType.NestedType);
            }

            internal MethodBase GetMethod(RuntimeTypeHandle declaringType, RuntimeMethodHandle method) 
            {
                GetMemberCache(ref m_methodInfoCache); 
                return m_methodInfoCache.AddMethod(declaringType, method, CacheType.Method); 
            }
 
            internal MethodBase GetConstructor(RuntimeTypeHandle declaringType, RuntimeMethodHandle constructor)
            {
                GetMemberCache(ref m_constructorInfoCache);
                return m_constructorInfoCache.AddMethod(declaringType, constructor, CacheType.Constructor); 
            }
 
            internal FieldInfo GetField(RuntimeFieldHandle field) 
            {
                GetMemberCache(ref m_fieldInfoCache); 
                return m_fieldInfoCache.AddField(field);
            }

            #endregion 
        }
        #endregion 
 
        #region Static Members
 
        #region Internal
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        static internal extern void PrepareMemberInfoCache(RuntimeTypeHandle rt);
 
        internal static MethodBase GetMethodBase(ModuleHandle scope, int typeMetadataToken)
        { 
            return GetMethodBase(scope.ResolveMethodHandle(typeMetadataToken)); 
        }
 
        internal static MethodBase GetMethodBase(Module scope, int typeMetadataToken)
        {
            return GetMethodBase(scope.GetModuleHandle(), typeMetadataToken);
        } 

        internal static MethodBase GetMethodBase(RuntimeMethodHandle methodHandle) 
        { 
            return GetMethodBase(RuntimeTypeHandle.EmptyHandle, methodHandle);
        } 

        internal unsafe static MethodBase GetMethodBase(RuntimeTypeHandle reflectedTypeHandle, RuntimeMethodHandle methodHandle)
        {
            ASSERT.CONSISTENCY_CHECK(!reflectedTypeHandle.IsNullHandle()); 
            ASSERT.CONSISTENCY_CHECK(!methodHandle.IsNullHandle());
 
            if (methodHandle.IsDynamicMethod()) 
            {
                Resolver resolver = methodHandle.GetResolver(); 

                if (resolver != null)
                    return resolver.GetDynamicMethod();
 
                return null;
            } 
 
            // verify the type/method relationship
            Type declaredType = methodHandle.GetDeclaringType().GetRuntimeType(); 
            RuntimeType reflectedType = reflectedTypeHandle.GetRuntimeType();

            RuntimeTypeHandle[] methodInstantiation = null;
            bool fNeedInstantiatingStub = false; 

            if (reflectedType == null) 
                reflectedType = declaredType as RuntimeType; 

            if (reflectedType.IsArray) 
            {
                MethodBase[] methodBases = reflectedType.GetMember(
                    methodHandle.GetName(), MemberTypes.Constructor | MemberTypes.Method,
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) as MethodBase[]; 

                bool loaderAssuredCompatible = false; 
                for (int i = 0; i < methodBases.Length; i ++) 
                {
                    if (methodBases[i].GetMethodHandle() == methodHandle) 
                        loaderAssuredCompatible = true;
                }

                if (!loaderAssuredCompatible) 
                    throw new ArgumentException(String.Format(
                        CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"), 
                        reflectedType.ToString(), declaredType.ToString())); 

                declaredType = reflectedType; 
            }
            else if (!declaredType.IsAssignableFrom(reflectedType))
            {
                if (!declaredType.IsGenericType) 
                    throw new ArgumentException(String.Format(
                        CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"), 
                        reflectedType.ToString(), declaredType.ToString())); 

                // ignoring instantiation is the ReflectedType a subtype of the DeclaringType 
                Type declaringDefinition = declaredType.GetGenericTypeDefinition();

                Type baseType = reflectedType;
 
                while (baseType != null)
                { 
                    Type baseDefinition = baseType; 

                    if (baseDefinition.IsGenericType && !baseType.IsGenericTypeDefinition) 
                        baseDefinition = baseDefinition.GetGenericTypeDefinition();

                    if (baseDefinition.Equals(declaringDefinition))
                        break; 

                    baseType = baseType.BaseType; 
                } 

                if (baseType == null) 
                {
                    // ignoring instantiation is the ReflectedType is not a subtype of the DeclaringType
                    throw new ArgumentException(String.Format(
                        CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"), 
                        reflectedType.ToString(), declaredType.ToString()));
                } 
 
                // remap the method to same method on the subclass ReflectedType
                declaredType = baseType; 

                methodInstantiation = methodHandle.GetMethodInstantiation();

                bool bIsGenericMethodDefinition = methodHandle.IsGenericMethodDefinition(); 

                // lookup via v-table slot the RuntimeMethodHandle on the new declaring type 
                methodHandle = methodHandle.GetMethodFromCanonical(declaredType.GetTypeHandleInternal()); 

                // if the original methodHandle was the definition then we don't need to rebind generic method arguments 
                // because all RuntimeMethodHandles retrieved off of the canonical method table are definitions. That's
                // why for everything else we need to rebind the generic method arguments.
                if (!bIsGenericMethodDefinition)
                { 
                    fNeedInstantiatingStub = true;
                } 
            } 

            if (declaredType.IsValueType) 
                methodHandle = methodHandle.GetUnboxingStub();

            if ( fNeedInstantiatingStub ||
                 ( declaredType.GetTypeHandleInternal().HasInstantiation() && 
                   !declaredType.GetTypeHandleInternal().IsGenericTypeDefinition() &&
                   !methodHandle.HasMethodInstantiation())) 
            { 
                // if declaredType is an instantiated type and methodHandle is not generic get the instantiated MethodDesc (if needed)
                // MemberInfoCache.PopulateMethods and MemberInfoCache.PopulateConstructors do this already 
                methodHandle = methodHandle.GetInstantiatingStub(declaredType.GetTypeHandleInternal(), methodInstantiation);
            }

            if (methodHandle.IsConstructor()) 
            {
                // Constructor case: constructors cannot be generic 
                return reflectedType.Cache.GetConstructor(declaredType.GetTypeHandleInternal(), methodHandle); 
            }
            else 
            {
                // Method case
                if (methodHandle.HasMethodInstantiation() && !methodHandle.IsGenericMethodDefinition())
                    return reflectedType.Cache.GetGenericMethodInfo(methodHandle); 
                else
                    return reflectedType.Cache.GetMethod(declaredType.GetTypeHandleInternal(), methodHandle); 
            } 
        }
 
        internal bool DomainInitialized
        {
            get { return Cache.DomainInitialized; }
            set { Cache.DomainInitialized = value; } 
        }
 
        internal unsafe static FieldInfo GetFieldInfo(RuntimeFieldHandle fieldHandle) 
        {
            return GetFieldInfo(fieldHandle.GetApproxDeclaringType(), fieldHandle); 
        }

        internal unsafe static FieldInfo GetFieldInfo(RuntimeTypeHandle reflectedTypeHandle, RuntimeFieldHandle fieldHandle)
        { 
            // verify the type/method relationship
            if (reflectedTypeHandle.IsNullHandle()) 
            { 
                reflectedTypeHandle = fieldHandle.GetApproxDeclaringType();
            } 
            else
            {
                RuntimeTypeHandle declaredTypeHandle = fieldHandle.GetApproxDeclaringType();
                if (!reflectedTypeHandle.Equals(declaredTypeHandle)) 
                {
                    if (!fieldHandle.AcquiresContextFromThis() || 
                        !declaredTypeHandle.GetCanonicalHandle().Equals(reflectedTypeHandle.GetCanonicalHandle())) 
                    {
                        throw new ArgumentException(String.Format( 
                            CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveFieldHandle"),
                            reflectedTypeHandle.GetRuntimeType().ToString(),
                            declaredTypeHandle.GetRuntimeType().ToString()));
                    } 
                }
            } 
 
            return reflectedTypeHandle.GetRuntimeType().Cache.GetField(fieldHandle);
        } 

        // Called internally
        internal unsafe static PropertyInfo GetPropertyInfo(RuntimeTypeHandle reflectedTypeHandle, int tkProperty)
        { 
            RuntimePropertyInfo property = null;
            CerArrayList candidates = 
                reflectedTypeHandle.GetRuntimeType().Cache.GetPropertyList(MemberListType.All, null); 

            for (int i = 0; i < candidates.Count; i++) 
            {
                property = candidates[i];
                if (property.MetadataToken == tkProperty)
                    return property; 
            }
 
            ASSERT.UNREACHABLE(); 
            throw new SystemException();
        } 

        private static void ThrowIfTypeNeverValidGenericArgument(Type type)
        {
            if (type.IsPointer || type.IsByRef || type == typeof(void)) 
                throw new ArgumentException(
                    String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_NeverValidGenericArgument"), type.ToString())); 
        } 

 
        internal static void SanityCheckGenericArguments(Type[] genericArguments, Type[] 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( 
                    String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_NotEnoughGenArguments", genericArguments.Length, genericParamters.Length))); 
        }
 
        internal static void ValidateGenericArguments(MemberInfo definition, Type[] genericArguments, Exception e)
        {
            RuntimeTypeHandle[] typeContextHandle = null;
            RuntimeTypeHandle[] methodContextHandle = null; 
            Type[] genericParamters = null;
 
            if (definition is Type) 
            {
                Type genericTypeDefinition = (Type)definition; 
                genericParamters = genericTypeDefinition.GetGenericArguments();
                typeContextHandle = new RuntimeTypeHandle[genericArguments.Length];
                for (int i = 0; i < genericArguments.Length; i ++)
                    typeContextHandle[i] = genericArguments[i].GetTypeHandleInternal(); 
            }
            else 
            { 
                MethodInfo genericMethodDefinition = (MethodInfo)definition;
                genericParamters = genericMethodDefinition.GetGenericArguments(); 
                methodContextHandle = new RuntimeTypeHandle[genericArguments.Length];
                for (int i = 0; i < genericArguments.Length; i ++)
                    methodContextHandle[i] = genericArguments[i].GetTypeHandleInternal();
 
                Type declaringType = genericMethodDefinition.DeclaringType;
                if (declaringType != null) 
                    typeContextHandle = declaringType.GetTypeHandleInternal().GetInstantiation(); 
            }
 
            for (int i = 0; i < genericArguments.Length; i++)
            {
                Type genericArgument = genericArguments[i];
                Type genericParameter = genericParamters[i]; 

                if (!genericParameter.GetTypeHandleInternal().SatisfiesConstraints( 
                    typeContextHandle, methodContextHandle, genericArgument.GetTypeHandleInternal())) 
                {
                    throw new ArgumentException( 
                        String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_GenConstraintViolation"),
                        i.ToString(CultureInfo.CurrentCulture), genericArgument.ToString(), definition.ToString(), genericParameter.ToString()), e);
                }
            } 
        }
 
        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 = ""; 
                ASSERT.CONSISTENCY_CHECK(fullname.Equals(ns + "." + name)); 
            }
            else 
            {
                name = fullname;
            }
 
        }
        #endregion 
 
        #region Filters
        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;
        } 

        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))
                { 
                    name = name.Substring(0, name.Length - 1);
                    prefixLookup = true;
                    listType = MemberListType.All;
                } 
            }
            else 
            { 
                listType = MemberListType.All;
            } 
        }

        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); 
        } 

        private static bool FilterApplyPrefixLookup(MemberInfo memberInfo, string name, bool ignoreCase) 
        {
            ASSERT.CONSISTENCY_CHECK(name != null);

            if (ignoreCase) 
            {
                if (!memberInfo.Name.ToLower(CultureInfo.InvariantCulture).StartsWith(name, StringComparison.Ordinal)) 
                    return false; 
            }
            else 
            {
                if (!memberInfo.Name.StartsWith(name, StringComparison.Ordinal))
                    return false;
            } 

            return true; 
        } 

 
        private static bool FilterApplyBase(
            MemberInfo memberInfo, BindingFlags bindingFlags, bool isPublic, bool isNonProtectedInternal, bool isStatic,
            string name, bool prefixLookup)
        { 
            #region Preconditions
            ASSERT.PRECONDITION(memberInfo != null); 
            ASSERT.PRECONDITION(name == null || (bindingFlags & BindingFlags.IgnoreCase) == 0 || (name.ToLower(CultureInfo.InvariantCulture).Equals(name))); 
            #endregion
 
            #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 = 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;
        } 


        private static bool FilterApplyType(
            Type type, BindingFlags bindingFlags, string name, bool prefixLookup, string ns) 
        {
            ASSERT.PRECONDITION(type != null); 
            ASSERT.PRECONDITION(type is RuntimeType); 

            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 && !type.Namespace.Equals(ns)) 
                return false; 

            return true; 
        }


        private static bool FilterApplyMethodBaseInfo( 
            MethodBase methodBase, BindingFlags bindingFlags, string name, CallingConventions callConv, Type[] argumentTypes,
            bool prefixLookup) 
        { 
            ASSERT.PRECONDITION(methodBase != null);
 
            #region Apply Base Filter
            bindingFlags ^= BindingFlags.DeclaredOnly;
            BindingFlags matchFlags;
 
            RuntimeMethodInfo methodInfo = methodBase as RuntimeMethodInfo;
            if (methodInfo == null) 
            { 
                RuntimeConstructorInfo constructorInfo = methodBase as RuntimeConstructorInfo;
                matchFlags = constructorInfo.BindingFlags; 
            }
            else
            {
                matchFlags = methodInfo.BindingFlags; 
            }
 
            if ((bindingFlags & matchFlags) != matchFlags || 
                (prefixLookup && !FilterApplyPrefixLookup(methodBase, name, (bindingFlags & BindingFlags.IgnoreCase) != 0)))
                return false; 
            #endregion

            return FilterApplyMethodBaseInfo(methodBase, bindingFlags, callConv, argumentTypes);
        } 

 
        private static bool FilterApplyMethodBaseInfo( 
            MethodBase methodBase, BindingFlags bindingFlags, CallingConventions callConv, Type[] argumentTypes)
        { 
            #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. 
                            ASSERT.CONSISTENCY_CHECK((callConv & CallingConventions.VarArgs) != 0); 
                        }
                        #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 (argumentTypes[i] != null && parameterInfos[i].ParameterType != argumentTypes[i]) 
                                    return false; 
                            }
                        } 
                    }
                    #endregion
                }
            } 
            #endregion
 
            return true; 
        }
 
        #endregion

        #endregion
 
        #region Private Data Members
        private IntPtr m_cache; 
        private RuntimeTypeHandle m_handle; 

        private class TypeCacheQueue 
        {
            // must be a power of 2 for this to work
            const int QUEUE_SIZE = 4;
 
            Object[] liveCache;
 
            internal TypeCacheQueue() 
            {
                liveCache = new Object[QUEUE_SIZE]; 
            }
        }
        private static TypeCacheQueue s_typeCache = null;
        #endregion 

        #region Constructor 
        private RuntimeType(RuntimeTypeHandle typeHandle) 
        {
            m_handle = typeHandle; 
        }

        internal RuntimeType() {}
        #endregion 

        #region Private\Internal Members 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
        internal override bool CacheEquals(object o)
        { 
            RuntimeType m = o as RuntimeType;

            if (m == null)
                return false; 

            return m.m_handle.Equals(m_handle); 
        } 

        private new RuntimeTypeCache Cache 
        {
            get
            {
                if (m_cache.IsNull()) 
                {
                    IntPtr newgcHandle = m_handle.GetGCHandle(GCHandleType.WeakTrackResurrection); 
                    IntPtr gcHandle = Interlocked.CompareExchange(ref m_cache, newgcHandle, (IntPtr)0); 
                    if (!gcHandle.IsNull())
                        m_handle.FreeGCHandle(newgcHandle); 
                }

                RuntimeTypeCache cache = GCHandle.InternalGet(m_cache) as RuntimeTypeCache;
                if (cache == null) 
                {
                    cache = new RuntimeTypeCache(this); 
                    RuntimeTypeCache existingCache = GCHandle.InternalCompareExchange(m_cache, cache, null, false) as RuntimeTypeCache; 
                    if (existingCache != null)
                        cache = existingCache; 
                    if (s_typeCache == null)
                        s_typeCache = new TypeCacheQueue();
                    //s_typeCache.Add(cache);
                } 
/*
                RuntimeTypeCache cache = m_cache as RuntimeTypeCache; 
                if (cache == null) 
                {
                    cache = new RuntimeTypeCache(TypeHandle); 
                    RuntimeTypeCache existingCache = Interlocked.CompareExchange(ref m_cache, cache, null) as RuntimeTypeCache;
                    if (existingCache != null)
                        cache = existingCache;
                } 
*/
                ASSERT.CONSISTENCY_CHECK(cache != null); 
                return cache; 
            }
        } 
        #endregion

        #region Type Overrides
 
        #region Get XXXInfo Candidates
        private MethodInfo[] GetMethodCandidates( 
            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);
 
            List candidates = new List();
            CerArrayList cache = Cache.GetMethodList(listType, name); 
 
            bindingAttr ^= BindingFlags.DeclaredOnly;
 
            for (int i = 0; i < cache.Count; i++)
            {
                RuntimeMethodInfo methodInfo = cache[i];
                if ((bindingAttr & methodInfo.BindingFlags) == methodInfo.BindingFlags && 
                    FilterApplyMethodBaseInfo(methodInfo, bindingAttr, callConv, types) &&
                    (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(methodInfo, name, ignoreCase))) 
                { 
                    candidates.Add(methodInfo);
                } 
            }

            return candidates.ToArray();
        } 

 
        private 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); 

            List candidates = new List(); 
            CerArrayList cache = Cache.GetConstructorList(listType, name); 

            bindingAttr ^= BindingFlags.DeclaredOnly; 

            for (int i = 0; i < cache.Count; i++)
            {
                RuntimeConstructorInfo constructorInfo = cache[i]; 
                if ((bindingAttr & constructorInfo.BindingFlags) == constructorInfo.BindingFlags &&
                    FilterApplyMethodBaseInfo(constructorInfo, bindingAttr, callConv, types) && 
                    (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(constructorInfo, name, ignoreCase))) 
                {
                    candidates.Add(constructorInfo); 
                }
            }

            return candidates.ToArray(); 
        }
 
 
        private 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); 

            List candidates = new List(); 
            CerArrayList cache = Cache.GetPropertyList(listType, name); 

            bindingAttr ^= BindingFlags.DeclaredOnly; 

            for (int i = 0; i < cache.Count; 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.ToArray(); 
        }
 
 
        private 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);
 
            List candidates = new List();
            CerArrayList cache = Cache.GetEventList(listType, name); 
 
            bindingAttr ^= BindingFlags.DeclaredOnly;
 
            for (int i = 0; i < cache.Count; i++)
            {
                RuntimeEventInfo eventInfo = cache[i];
                if ((bindingAttr & eventInfo.BindingFlags) == eventInfo.BindingFlags && 
                    (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(eventInfo, name, ignoreCase)))
                { 
                    candidates.Add(eventInfo); 
                }
            } 

            return candidates.ToArray();
        }
 
        private 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); 

            List candidates = new List();
            CerArrayList cache = Cache.GetFieldList(listType, name);
 
            bindingAttr ^= BindingFlags.DeclaredOnly;
 
            for (int i = 0; i < cache.Count; i++) 
            {
                RuntimeFieldInfo fieldInfo = cache[i]; 
                if ((bindingAttr & fieldInfo.BindingFlags) == fieldInfo.BindingFlags &&
                    (!prefixLookup || FilterApplyPrefixLookup(fieldInfo, name, ignoreCase)))
                {
                    candidates.Add(fieldInfo); 
                }
            } 
 
            return candidates.ToArray();
        } 

        private 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); 

            List candidates = new List();
            CerArrayList cache = Cache.GetNestedTypeList(listType, name);
 
            for (int i = 0; i < cache.Count; i++)
            { 
                RuntimeType nestedClass = cache[i]; 
                if (RuntimeType.FilterApplyType(nestedClass, bindingAttr, name, prefixLookup, ns))
                { 
                    candidates.Add(nestedClass);
                }
            }
 
            return candidates.ToArray();
        } 
        #endregion 

        #region Get All XXXInfos 
        public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
        {
            return GetMethodCandidates(null, bindingAttr, CallingConventions.Any, null, false);
        } 

[System.Runtime.InteropServices.ComVisible(true)] 
        public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) 
        {
            return GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, null, false); 
        }

        public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
        { 
            return GetPropertyCandidates(null, bindingAttr, null, false);
        } 
 
        public override EventInfo[] GetEvents(BindingFlags bindingAttr)
        { 
            return GetEventCandidates(null, bindingAttr, false);
        }

        public override FieldInfo[] GetFields(BindingFlags bindingAttr) 
        {
            return GetFieldCandidates(null, bindingAttr, false); 
        } 

        public override Type[] GetInterfaces() 
        {
              CerArrayList candidates = this.Cache.GetInterfaceList(MemberListType.All, null);
              Type[] interfaces = new Type[candidates.Count];
              for (int i = 0; i < candidates.Count; i++) 
                  JitHelpers.UnsafeSetArrayElement(interfaces, i, candidates[i]);
 
              return interfaces; 
        }
 
        public override Type[] GetNestedTypes(BindingFlags bindingAttr)
        {
            return GetNestedTypeCandidates(null, bindingAttr, false);
        } 

        public override MemberInfo[] GetMembers(BindingFlags bindingAttr) 
        { 
            MethodInfo[] methods = GetMethodCandidates(null, bindingAttr, CallingConventions.Any, null, false);
            ConstructorInfo[] constructors = GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, null, false); 
            PropertyInfo[] properties = GetPropertyCandidates(null, bindingAttr, null, false);
            EventInfo[] events = GetEventCandidates(null, bindingAttr, false);
            FieldInfo[] fields = GetFieldCandidates(null, bindingAttr, false);
            Type[] nestedTypes = GetNestedTypeCandidates(null, bindingAttr, false); 
            // Interfaces are excluded from the result of GetMembers
 
            MemberInfo[] members = new MemberInfo[ 
                methods.Length +
                constructors.Length + 
                properties.Length +
                events.Length +
                fields.Length +
                nestedTypes.Length]; 

            int i = 0; 
            Array.Copy(methods, 0, members, i, methods.Length); i += methods.Length; 
            Array.Copy(constructors, 0, members, i, constructors.Length); i += constructors.Length;
            Array.Copy(properties, 0, members, i, properties.Length); i += properties.Length; 
            Array.Copy(events, 0, members, i, events.Length); i += events.Length;
            Array.Copy(fields, 0, members, i, fields.Length); i += fields.Length;
            Array.Copy(nestedTypes, 0, members, i, nestedTypes.Length); i += nestedTypes.Length;
 
            ASSERT.POSTCONDITION(i == members.Length);
            return members; 
        } 

        public override InterfaceMapping GetInterfaceMap(Type ifaceType) 
        {
            if (IsGenericParameter)
                throw new InvalidOperationException(Environment.GetResourceString("Arg_GenericParameter"));
 
            if (ifaceType == null)
                throw new ArgumentNullException("ifaceType"); 
 
            if (!(ifaceType is RuntimeType))
                throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "ifaceType"); 

            RuntimeType ifaceRtType = ifaceType as RuntimeType;
            RuntimeTypeHandle ifaceRtTypeHandle = ifaceRtType.GetTypeHandleInternal();
 
            int firstIfaceSlot = GetTypeHandleInternal().GetFirstSlotForInterface(ifaceRtType.GetTypeHandleInternal());
            ASSERT.CONSISTENCY_CHECK(ifaceType.IsInterface);  // GetFirstSlotForInterface enforces this invariant 
            ASSERT.CONSISTENCY_CHECK(!IsInterface); // GetFirstSlotForInterface enforces this invariant 

            int ifaceSlotCount = ifaceRtTypeHandle.GetInterfaceMethodSlots(); 
            int ifaceStaticMethodCount = 0;

            // @Optimization - Most interface have the same number of static members.
 
            // Filter out static methods
            for (int i = 0; i < ifaceSlotCount; i ++) 
            { 
                if ((ifaceRtTypeHandle.GetMethodAt(i).GetAttributes() & MethodAttributes.Static) != 0)
                    ifaceStaticMethodCount++; 
            }

            int ifaceInstanceMethodCount = ifaceSlotCount - ifaceStaticMethodCount;
 
            InterfaceMapping im;
            im.InterfaceType = ifaceType; 
            im.TargetType = this; 
            im.InterfaceMethods = new MethodInfo[ifaceInstanceMethodCount];
            im.TargetMethods = new MethodInfo[ifaceInstanceMethodCount]; 

            for(int i = 0; i < ifaceSlotCount; i++)
            {
                RuntimeMethodHandle ifaceRtMethodHandle = ifaceRtTypeHandle.GetMethodAt(i); 
                if ((ifaceRtTypeHandle.GetMethodAt(i).GetAttributes() & MethodAttributes.Static) != 0)
                    continue; 
 
                bool mayNeedInstantiatingStub = ifaceRtTypeHandle.HasInstantiation() && !ifaceRtTypeHandle.IsGenericTypeDefinition();
 
                // if it is an instantiated type get the InstantiatedMethodDesc if needed
                if (mayNeedInstantiatingStub)
                    ifaceRtMethodHandle = ifaceRtMethodHandle.GetInstantiatingStubIfNeeded(ifaceRtTypeHandle);
 
                MethodBase ifaceMethodBase = RuntimeType.GetMethodBase(ifaceRtTypeHandle, ifaceRtMethodHandle);
                ASSERT.CONSISTENCY_CHECK(ifaceMethodBase is RuntimeMethodInfo); 
                im.InterfaceMethods[i] = (MethodInfo)ifaceMethodBase; 

                // If the slot is -1, then virtual stub dispatch is active. 
                // Should remove old "firstIfaceSlot + i" code when old behaviour disappears.
                int slot;
                if (firstIfaceSlot == -1)
                    slot = GetTypeHandleInternal().GetInterfaceMethodImplementationSlot(ifaceRtTypeHandle, ifaceRtMethodHandle); 
                else
                    slot = firstIfaceSlot + i; 
 
                if (slot == -1) continue;
 

                RuntimeTypeHandle classRtTypeHandle = GetTypeHandleInternal();
                RuntimeMethodHandle classRtMethodHandle = classRtTypeHandle.GetMethodAt(slot);
 
                mayNeedInstantiatingStub = classRtTypeHandle.HasInstantiation() && !classRtTypeHandle.IsGenericTypeDefinition();
 
                if (mayNeedInstantiatingStub) 
                    classRtMethodHandle = classRtMethodHandle.GetInstantiatingStubIfNeeded(classRtTypeHandle);
 
                MethodBase rtTypeMethodBase = RuntimeType.GetMethodBase(classRtTypeHandle, classRtMethodHandle);
                // a class may not implement all the methods of an interface (abstract class) so null is a valid value
                ASSERT.CONSISTENCY_CHECK(rtTypeMethodBase == null || rtTypeMethodBase is RuntimeMethodInfo);
                im.TargetMethods[i] = (MethodInfo)rtTypeMethodBase; 
            }
 
            return im; 
        }
        #endregion 

        #region Find XXXInfo
        protected override MethodInfo GetMethodImpl(
            String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConv, 
            Type[] types, ParameterModifier[] modifiers)
        { 
            MethodInfo[] candidates = GetMethodCandidates(name, bindingAttr, callConv, types, false); 

            if (candidates.Length == 0) 
                return null;

            if (types == null || types.Length == 0)
            { 
                if (candidates.Length == 1)
                { 
                    return candidates[0]; 
                }
                else if (types == null) 
                {
                    for (int j = 1; j < candidates.Length; j++)
                    {
                        MethodInfo methodInfo = candidates[j]; 
                        if (!System.DefaultBinder.CompareMethodSigAndName(methodInfo, candidates[0]))
                        { 
                            throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.Ambiguous")); 
                        }
                    } 

                    // All the methods have the exact same name and sig so return the most derived one.
                    return System.DefaultBinder.FindMostDerivedNewSlotMeth(candidates, candidates.Length) as MethodInfo;
                } 
            }
 
            if (binder == null) 
                binder = DefaultBinder;
 
            return binder.SelectMethod(bindingAttr, candidates, types, modifiers) as MethodInfo;
        }

 
        protected override ConstructorInfo GetConstructorImpl(
            BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, 
            Type[] types, ParameterModifier[] modifiers) 
        {
            ConstructorInfo[] candidates = GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, types, false); 

            if (binder == null)
                binder = DefaultBinder;
 
            if (candidates.Length == 0)
                return null; 
 
            if (types.Length == 0 && candidates.Length == 1)
            { 
                ParameterInfo[] parameters = (candidates[0]).GetParametersNoCopy();
                if (parameters == null || parameters.Length == 0)
                {
                    return candidates[0]; 
                }
            } 
 
            if ((bindingAttr & BindingFlags.ExactBinding) != 0)
                return System.DefaultBinder.ExactBinding(candidates, types, modifiers) as ConstructorInfo; 

            return binder.SelectMethod(bindingAttr, candidates, 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(); 

            PropertyInfo[] candidates = GetPropertyCandidates(name, bindingAttr, types, false);

            if (binder == null) 
                binder = DefaultBinder;
 
            if (candidates.Length == 0) 
                return null;
 
            if (types == null || types.Length == 0)
            {
                // no arguments
                if (candidates.Length == 1) 
                {
                    if (returnType != null && returnType != candidates[0].PropertyType) 
                        return null; 

                    return candidates[0]; 
                }
                else
                {
                    if (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(Environment.GetResourceString("RFLCT.Ambiguous")); 
                } 
            }
 
            if ((bindingAttr & BindingFlags.ExactBinding) != 0)
                return System.DefaultBinder.ExactPropertyBinding(candidates, returnType, types, modifiers);

            return binder.SelectProperty(bindingAttr, candidates, 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);
 
            CerArrayList cache = Cache.GetEventList(listType, name); 
            EventInfo match = null;
 
            bindingAttr ^= BindingFlags.DeclaredOnly;

            for (int i = 0; i < cache.Count; i++)
            { 
                RuntimeEventInfo eventInfo = cache[i];
                if ((bindingAttr & eventInfo.BindingFlags) == eventInfo.BindingFlags) 
                { 
                    if (match != null)
                        throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.Ambiguous")); 

                    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); 
 
            CerArrayList cache = Cache.GetFieldList(listType, name);
            FieldInfo match = null; 

            bindingAttr ^= BindingFlags.DeclaredOnly;
            bool multipleStaticFieldMatches = false;
 
            for (int i = 0; i < cache.Count; i++)
            { 
                RuntimeFieldInfo fieldInfo = cache[i]; 
                if ((bindingAttr & fieldInfo.BindingFlags) == fieldInfo.BindingFlags)
                { 
                    if (match != null)
                    {
                        if (fieldInfo.DeclaringType == match.DeclaringType)
                            throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.Ambiguous")); 

                        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(Environment.GetResourceString("RFLCT.Ambiguous")); 

            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);
 
            CerArrayList cache = Cache.GetInterfaceList(listType, name);

            RuntimeType match = null;
 
            for (int i = 0; i < cache.Count; i++)
            { 
                RuntimeType iface = cache[i]; 
                if (RuntimeType.FilterApplyType(iface, bindingAttr, name, false, ns))
                { 
                    if (match != null)
                        throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.Ambiguous"));

                    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);

            CerArrayList cache = Cache.GetNestedTypeList(listType, name); 

            RuntimeType match = null; 
 
            for (int i = 0; i < cache.Count; i++)
            { 
                RuntimeType nestedType = cache[i];
                if (RuntimeType.FilterApplyType(nestedType, bindingAttr, name, false, ns))
                {
                    if (match != null) 
                        throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.Ambiguous"));
 
                    match = nestedType; 
                }
            } 

            return match;
        }
 
        public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
        { 
            if (name == null) throw new ArgumentNullException(); 

            MethodInfo[] methods = new MethodInfo[0]; 
            ConstructorInfo[] constructors = new ConstructorInfo[0];
            PropertyInfo[] properties = new PropertyInfo[0];
            EventInfo[] events = new EventInfo[0];
            FieldInfo[] fields = new FieldInfo[0]; 
            Type[] nestedTypes = new Type[0];
 
            // Methods 
            if ((type & MemberTypes.Method) != 0)
                methods = GetMethodCandidates(name, bindingAttr, CallingConventions.Any, null, true); 

            // Constructors
            if ((type & MemberTypes.Constructor) != 0)
                constructors = GetConstructorCandidates(name, bindingAttr, CallingConventions.Any, null, true); 

            // Properties 
            if ((type & MemberTypes.Property) != 0) 
                properties = GetPropertyCandidates(name, bindingAttr, null, true);
 
            // Events
            if ((type & MemberTypes.Event) != 0)
                events = GetEventCandidates(name, bindingAttr, true);
 
            // Fields
            if ((type & MemberTypes.Field) != 0) 
                fields = GetFieldCandidates(name, bindingAttr, true); 

            // NestedTypes 
            if ((type & (MemberTypes.NestedType | MemberTypes.TypeInfo)) != 0)
                nestedTypes = GetNestedTypeCandidates(name, bindingAttr, true);

            switch(type) 
            {
                case MemberTypes.Method | MemberTypes.Constructor: 
                    MethodBase[] compressBaseses = new MethodBase[methods.Length + constructors.Length]; 
                    Array.Copy(methods, compressBaseses, methods.Length);
                    Array.Copy(constructors, 0, compressBaseses, methods.Length, constructors.Length); 
                    return compressBaseses;

                case MemberTypes.Method:
                    return methods; 

                case MemberTypes.Constructor: 
                    return constructors; 

                case MemberTypes.Field: 
                    return fields;

                case MemberTypes.Property:
                    return properties; 

                case MemberTypes.Event: 
                    return events; 

                case MemberTypes.NestedType: 
                    return nestedTypes;

                case MemberTypes.TypeInfo:
                    return nestedTypes; 
            }
 
            MemberInfo[] compressMembers = new MemberInfo[ 
                methods.Length +
                constructors.Length + 
                properties.Length +
                events.Length +
                fields.Length +
                nestedTypes.Length]; 

            int i = 0; 
            if (methods.Length > 0) Array.Copy(methods, 0, compressMembers, i, methods.Length); i += methods.Length; 
            if (constructors.Length > 0) Array.Copy(constructors, 0, compressMembers, i, constructors.Length); i += constructors.Length;
            if (properties.Length > 0) Array.Copy(properties, 0, compressMembers, i, properties.Length); i += properties.Length; 
            if (events.Length > 0) Array.Copy(events, 0, compressMembers, i, events.Length); i += events.Length;
            if (fields.Length > 0) Array.Copy(fields, 0, compressMembers, i, fields.Length); i += fields.Length;
            if (nestedTypes.Length > 0) Array.Copy(nestedTypes, 0, compressMembers, i, nestedTypes.Length); i += nestedTypes.Length;
 
            ASSERT.POSTCONDITION(i == compressMembers.Length);
            return compressMembers; 
        } 
        #endregion
 
        #region Identity
        public override Module Module
        {
            get 
            {
                return GetTypeHandleInternal().GetModuleHandle().GetModule(); 
            } 
        }
 
        public override Assembly Assembly
        {
            get
            { 
                return GetTypeHandleInternal().GetAssemblyHandle().GetAssembly();
            } 
        } 

        public override RuntimeTypeHandle TypeHandle 
        {
            get
            {
                return m_handle; 
            }
        } 
 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        internal override RuntimeTypeHandle GetTypeHandleInternal() 
        {
            return m_handle;
        }
 
        internal override TypeCode GetTypeCodeInternal()
        { 
            TypeCode typeCode = Cache.TypeCode; 

            if (typeCode != TypeCode.Empty) 
                return typeCode;

            CorElementType corElementType = GetTypeHandleInternal().GetCorElementType();
            switch (corElementType) 
            {
                case CorElementType.Boolean: 
                    typeCode = TypeCode.Boolean; break; 
                case CorElementType.Char:
                    typeCode = TypeCode.Char; break; 
                case CorElementType.I1:
                    typeCode = TypeCode.SByte; break;
                case CorElementType.U1:
                    typeCode = TypeCode.Byte; break; 
                case CorElementType.I2:
                    typeCode = TypeCode.Int16; break; 
                case CorElementType.U2: 
                    typeCode = TypeCode.UInt16; break;
                case CorElementType.I4: 
                    typeCode = TypeCode.Int32; break;
                case CorElementType.U4:
                    typeCode = TypeCode.UInt32; break;
                case CorElementType.I8: 
                    typeCode = TypeCode.Int64; break;
                case CorElementType.U8: 
                    typeCode = TypeCode.UInt64; break; 
                case CorElementType.R4:
                    typeCode = TypeCode.Single; break; 
                case CorElementType.R8:
                    typeCode = TypeCode.Double; break;
                case CorElementType.String:
                    typeCode = TypeCode.String; break; 
                case CorElementType.ValueType:
                    if (this == Convert.ConvertTypes[(int)TypeCode.Decimal]) 
                        typeCode = TypeCode.Decimal; 
                    else if (this == Convert.ConvertTypes[(int)TypeCode.DateTime])
                        typeCode = TypeCode.DateTime; 
                    else if (this.IsEnum)
                        typeCode = Type.GetTypeCode(Enum.GetUnderlyingType(this));
                    else
                        typeCode = TypeCode.Object; 
                    break;
                default: 
                    if (this == Convert.ConvertTypes[(int)TypeCode.DBNull]) 
                        typeCode = TypeCode.DBNull;
                    else if (this == Convert.ConvertTypes[(int)TypeCode.String]) 
                        typeCode = TypeCode.String;
                    else
                        typeCode = TypeCode.Object;
                    break; 
            }
 
            Cache.TypeCode = typeCode; 

            return typeCode; 
        }

        public override MethodBase DeclaringMethod
        { 
            get
            { 
                if (!IsGenericParameter) 
                    throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
 
                RuntimeMethodHandle declaringMethod = GetTypeHandleInternal().GetDeclaringMethod();

                if (declaringMethod.IsNullHandle())
                    return null; 

                return GetMethodBase(declaringMethod.GetDeclaringType(), declaringMethod); 
            } 
        }
        #endregion 

        #region Hierarchy
        public override bool IsInstanceOfType(Object o)
        { 
            return GetTypeHandleInternal().IsInstanceOfType(o);
        } 
 
[System.Runtime.InteropServices.ComVisible(true)]
        public override bool IsSubclassOf(Type type) 
        {
            if (type == null)
                throw new ArgumentNullException("type");
            ASSERT.PRECONDITION(type is RuntimeType); 

            Type baseType = BaseType; 
 
            while (baseType != null)
            { 
                if (baseType == type)
                    return true;

                baseType = baseType.BaseType; 
            }
 
            // pretty much everything is a subclass of object, even interfaces 
            // notice that interfaces are really odd because they do not have a BaseType
            // yet IsSubclassOf(typeof(object)) returns true 
            if (type == typeof(Object) && type != this)
                return true;

            return false; 
        }
 
        public override Type BaseType 
        {
            get 
            {
                if (IsInterface)
                    return null;
 
                if (m_handle.IsGenericVariable())
                { 
                    Type[] constraints = GetGenericParameterConstraints(); 

                    Type baseType = typeof(object); 

                    for (int i = 0; i < constraints.Length; i++)
                    {
                        Type constraint = 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 == typeof(object)) 
                    {
                        GenericParameterAttributes special; 
                        special = GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask; 
                        if ((special & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
                            baseType = typeof(ValueType); 
                    }

                    return baseType;
                } 

                return m_handle.GetBaseTypeHandle().GetRuntimeType(); 
            } 
        }
 
        public override Type UnderlyingSystemType
        {
            get
            { 
                // Origional Comment: Return the underlying Type that represents the IReflect Object.
                // For expando object, this is the (Object) IReflectInstance.GetType().  For Type object it is this. 
                return this; 
            }
        } 
        #endregion

        #region Name
        public override String FullName 
        {
            get 
            { 
                return Cache.GetFullName();
            } 
        }

        public override String AssemblyQualifiedName
        { 
            get
            { 
                if (!IsGenericTypeDefinition && ContainsGenericParameters) 
                    return null;
 
                return Assembly.CreateQualifiedName(this.Assembly.FullName, this.FullName);
            }
        }
 
        public override String Namespace
        { 
            get 
            {
                string ns = Cache.GetNameSpace(); 

                if (ns == null || ns.Length == 0)
                    return null;
 
                return ns;
            } 
        } 
        #endregion
 
        #region Attributes
        protected override TypeAttributes GetAttributeFlagsImpl()
        {
            return m_handle.GetAttributes(); 
        }
 
        public override Guid GUID 
        {
            get 
            {
                Guid result = new Guid ();
                GetGUID(ref result);
                return result; 
            }
        } 
 
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private extern void GetGUID(ref Guid result); 

        protected override bool IsContextfulImpl()
        {
            return GetTypeHandleInternal().IsContextful(); 
        }
 
        /* 
        protected override bool IsMarshalByRefImpl()
        { 
            return GetTypeHandleInternal().IsMarshalByRef();
        }
        */
 
        protected override bool IsByRefImpl()
        { 
            CorElementType corElemType = GetTypeHandleInternal().GetCorElementType(); 
            return (corElemType == CorElementType.ByRef);
        } 

        protected override bool IsPrimitiveImpl()
        {
            CorElementType corElemType = GetTypeHandleInternal().GetCorElementType(); 

            return 
                (corElemType >= CorElementType.Boolean && corElemType <= CorElementType.R8) || 
                corElemType == CorElementType.I ||
                corElemType == CorElementType.U; 
        }

        protected override bool IsPointerImpl()
        { 
            CorElementType corElemType = GetTypeHandleInternal().GetCorElementType();
            return (corElemType == CorElementType.Ptr); 
        } 

        protected override bool IsCOMObjectImpl() 
        {
            return GetTypeHandleInternal().IsComObject(false);
        }
 
        internal override bool HasProxyAttributeImpl()
        { 
            return GetTypeHandleInternal().HasProxyAttribute(); 
        }
 
        protected override bool HasElementTypeImpl()
        {
            return (IsArray || IsPointer || IsByRef);
        } 

        public override GenericParameterAttributes GenericParameterAttributes 
        { 
            get
            { 
                if (!IsGenericParameter)
                    throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));

                GenericParameterAttributes attributes; 

                GetTypeHandleInternal().GetModuleHandle().GetMetadataImport().GetGenericParamProps(MetadataToken, out attributes); 
 
                return attributes;
            } 
        }
        #endregion

        #region Arrays 
        internal override bool IsSzArray
        { 
            get 
            {
                CorElementType corElemType = GetTypeHandleInternal().GetCorElementType(); 
                return (corElemType == CorElementType.SzArray);
            }
        }
 
        protected override bool IsArrayImpl()
        { 
            CorElementType corElemType = GetTypeHandleInternal().GetCorElementType(); 
            return (corElemType == CorElementType.Array || corElemType == CorElementType.SzArray);
        } 

        public override int GetArrayRank()
        {
            if (!IsArrayImpl()) 
                throw new ArgumentException(Environment.GetResourceString("Argument_HasToBeArrayClass"));
 
            return GetTypeHandleInternal().GetArrayRank(); 
        }
 
        public override Type GetElementType()
        {
            return GetTypeHandleInternal().GetElementType().GetRuntimeType();
        } 
        #endregion
 
        #region Generics 
        public override Type[] GetGenericArguments()
        { 
            Type[] rtypes = null;
            RuntimeTypeHandle[] types = GetRootElementType().GetTypeHandleInternal().GetInstantiation();

            if (types != null) 
            {
                rtypes = new Type[types.Length]; 
 
                for (int i = 0; i < types.Length; i++)
                    rtypes[i] = types[i].GetRuntimeType(); 
            }
            else
            {
                rtypes = new Type[0]; 
            }
 
            return rtypes; 
        }
 
        public override Type MakeGenericType(Type[] instantiation)
        {
            if (instantiation == null)
                throw new ArgumentNullException("instantiation"); 

            Type[] instantiationCopy = new Type[instantiation.Length]; 
            for (int i = 0; i < instantiation.Length; i ++) 
                instantiationCopy[i] = instantiation[i];
            instantiation = instantiationCopy; 

            if (!IsGenericTypeDefinition)
                throw new InvalidOperationException(
                    String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Arg_NotGenericTypeDefinition"), this)); 

            for (int i = 0; i < instantiation.Length; i ++) 
            { 
                if (instantiation[i] == null)
                    throw new ArgumentNullException(); 

                if (!(instantiation[i] is RuntimeType))
                    return new TypeBuilderInstantiation(this, instantiation);
            } 

            Type[] genericParameters = GetGenericArguments(); 
 
            SanityCheckGenericArguments(instantiation, genericParameters);
 
            RuntimeTypeHandle[] typeHandles = new RuntimeTypeHandle[instantiation.Length];

            for (int i = 0; i < instantiation.Length; i++)
                typeHandles[i] = instantiation[i].GetTypeHandleInternal(); 

            Type ret = null; 
            try 
            {
                ret = m_handle.Instantiate(typeHandles).GetRuntimeType(); 
            }
            catch (TypeLoadException e)
            {
                ValidateGenericArguments(this, instantiation, e); 
                throw e;
            } 
 
            return ret;
        } 

        public override bool IsGenericTypeDefinition
        {
            get { return m_handle.IsGenericTypeDefinition(); } 
        }
 
        public override bool IsGenericParameter 
        {
            get { return m_handle.IsGenericVariable(); } 
        }

        public override int GenericParameterPosition
        { 
            get
            { 
                if (!IsGenericParameter) 
                    throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
 
                return m_handle.GetGenericVariableIndex();
            }
        }
 
        public override Type GetGenericTypeDefinition()
        { 
            if (!IsGenericType) 
                throw new InvalidOperationException();
 
            return m_handle.GetGenericTypeDefinition().GetRuntimeType();
        }

      	public override bool IsGenericType 
        {
            get { return HasElementType ? false : GetTypeHandleInternal().HasInstantiation(); } 
        } 

        public override bool ContainsGenericParameters 
        {
            get { return GetRootElementType().GetTypeHandleInternal().ContainsGenericVariables(); }
        }
 
        public override Type[] GetGenericParameterConstraints()
        { 
            if (!IsGenericParameter) 
                throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
 
            RuntimeTypeHandle[] constraintHandles = m_handle.GetConstraints();
            Type[] constraints = new Type[constraintHandles.Length];

            for (int i = 0; i < constraints.Length; i++) 
                constraints[i] = constraintHandles[i].GetRuntimeType();
 
            return constraints; 
        }
        #endregion 

        #region Misc
        public override Type MakePointerType() { return m_handle.MakePointer().GetRuntimeType(); }
        public override Type MakeByRefType() { return m_handle.MakeByRef().GetRuntimeType(); } 
        public override Type MakeArrayType() { return m_handle.MakeSZArray().GetRuntimeType(); }
        public override Type MakeArrayType(int rank) 
        { 
            if (rank <= 0)
                throw new IndexOutOfRangeException(); 

            return m_handle.MakeArray(rank).GetRuntimeType();
        }
        public override StructLayoutAttribute StructLayoutAttribute 
        {
            get 
            { 
                return (StructLayoutAttribute)StructLayoutAttribute.GetCustomAttribute(this);
            } 
        }
        #endregion

        #region Invoke Member 
        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 BinderSetInvokeProperty  = BindingFlags.InvokeMethod | BindingFlags.SetProperty; 
        private const BindingFlags BinderGetSetField        = BindingFlags.GetField | BindingFlags.SetField;
        private const BindingFlags BinderSetInvokeField     = BindingFlags.SetField | BindingFlags.InvokeMethod;
        private const BindingFlags BinderNonFieldGetSet     = (BindingFlags)0x00FFF300;
        private const BindingFlags ClassicBindingMask       = 
            BindingFlags.InvokeMethod | BindingFlags.GetProperty | BindingFlags.SetProperty |
            BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty; 
        private static Type s_typedRef = typeof(TypedReference); 

        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        static private extern bool CanValueSpecialCast(IntPtr valueType, IntPtr targetType);

        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        static private extern Object AllocateObjectForByRef(RuntimeTypeHandle type, object value); 

        internal unsafe Object CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr) 
        { 
            // this method is used by invocation in reflection to check whether a value can be assigned to type.
            if (IsInstanceOfType(value)) 
                return value;

            // if this is a ByRef get the element type and check if it's compatible
            bool isByRef = IsByRef; 
            if (isByRef)
            { 
                Type elementType = GetElementType(); 
                if (elementType.IsInstanceOfType(value) || value == null)
                { 
                    // need to create an instance of the ByRef if null was provided, but only if primitive, enum or value type
                    return AllocateObjectForByRef(elementType.TypeHandle, value);
                }
            } 
            else if (value == null)
                return value; 
            else if (this == s_typedRef) 
                // everything works for a typedref
                return value; 

            // check the strange ones courtesy of reflection:
            // - implicit cast between primitives
            // - enum treated as underlying type 
            // - IntPtr and System.Reflection.Pointer to pointer types
            bool needsSpecialCast = IsPointer || IsEnum || IsPrimitive; 
            if (needsSpecialCast) 
            {
                Type valueType; 
                Pointer pointer = value as Pointer;
                if (pointer != null)
                    valueType = pointer.GetPointerType();
                else 
                    valueType = value.GetType();
 
                if (CanValueSpecialCast(valueType.TypeHandle.Value, TypeHandle.Value)) 
                {
                    if (pointer != null) 
                        return pointer.GetPointerValue();
                    else
                        return value;
                } 
            }
 
            if ((invokeAttr & BindingFlags.ExactBinding) == BindingFlags.ExactBinding) 
                throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
 
            if (binder != null && binder != Type.DefaultBinder)
            {
                value = binder.ChangeType(value, this, culture);
                if (IsInstanceOfType(value)) 
                    return value;
                // if this is a ByRef get the element type and check if it's compatible 
                if (isByRef) 
                {
                    Type elementType = GetElementType(); 
                    if (elementType.IsInstanceOfType(value) || value == null)
                        return AllocateObjectForByRef(elementType.TypeHandle, value);
                }
                else if (value == null) 
                    return value;
                if (needsSpecialCast) 
                { 
                    Type valueType;
                    Pointer pointer = value as Pointer; 
                    if (pointer != null)
                        valueType = pointer.GetPointerType();
                    else
                        valueType = value.GetType(); 

                    if (CanValueSpecialCast(valueType.TypeHandle.Value, TypeHandle.Value)) 
                    { 
                        if (pointer != null)
                            return pointer.GetPointerValue(); 
                        else
                            return value;
                    }
                } 
            }
 
            throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this)); 
        }
 
        [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(Environment.GetResourceString("Arg_GenericParameter"));
 
            #region Preconditions
            if ((bindingFlags & InvocationMask) == 0)
                // "Must specify binding flags describing the invoke operation required."
                throw new ArgumentException(Environment.GetResourceString("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(Environment.GetResourceString("Arg_NamedParamTooBig"), "namedParams"); 
                }
                else 
                { 
                    if (namedParams.Length != 0)
                        // "Named parameter array can not be bigger than argument array." 
                        throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamTooBig"), "namedParams");
                }
            }
            #endregion 

            #region COM Interop 
#if FEATURE_COMINTEROP 
            if (target != null && target.GetType().IsCOMObject)
            { 
                #region Preconditions
                if ((bindingFlags & ClassicBindingMask) == 0)
                    throw new ArgumentException(Environment.GetResourceString("Arg_COMAccess"), "bindingFlags");
 
                if ((bindingFlags & BindingFlags.GetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
                    throw new ArgumentException(Environment.GetResourceString("Arg_PropSetGet"), "bindingFlags"); 
 
                if ((bindingFlags & BindingFlags.InvokeMethod) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
                    throw new ArgumentException(Environment.GetResourceString("Arg_PropSetInvoke"), "bindingFlags"); 

                if ((bindingFlags & BindingFlags.SetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.SetProperty) != 0)
                    throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags");
 
                if ((bindingFlags & BindingFlags.PutDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutDispProperty) != 0)
                    throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags"); 
 
                if ((bindingFlags & BindingFlags.PutRefDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutRefDispProperty) != 0)
                    throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags"); 
                #endregion

                if(!RemotingServices.IsTransparentProxy(target))
                { 
                    #region Non-TransparentProxy case
                    if (name == null) 
                        throw new ArgumentNullException("name"); 

                    if (culture == null) 
                        culture = Thread.CurrentThread.CurrentCulture;

                    bool[] isByRef = modifiers == null ? null : modifiers[0].IsByRefArray;
 
                    return InvokeDispMethod(name, bindingFlags, target, providedArgs, isByRef, culture.LCID, namedParams);
                    #endregion 
                } 
                else
                { 
                    #region TransparentProxy case
                    return ((MarshalByRefObject)target).InvokeMember(name, bindingFlags, binder, providedArgs, modifiers, culture, namedParams);
                    #endregion
                } 
            }
#endif // FEATURE_COMINTEROP 
            #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(Environment.GetResourceString("Arg_NamedParamNull"),"namedParams");
            #endregion 

            int argCnt = (providedArgs != null) ? providedArgs.Length : 0; 
 
            #region Get a Binder
            if (binder == null) 
                binder = DefaultBinder;

            bool bDefaultBinder = (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(Environment.GetResourceString("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(Environment.GetResourceString("Arg_FldSetGet"),"bindingFlags");
 
                    if ((bindingFlags & BindingFlags.SetProperty) != 0)
                        // "Can not specify both GetField and SetProperty." 
                        throw new ArgumentException(Environment.GetResourceString("Arg_FldGetPropSet"),"bindingFlags"); 
                }
                else 
                {
                    ASSERT.CONSISTENCY_CHECK(IsSetField);

                    if (providedArgs == null) 
                        throw new ArgumentNullException("providedArgs");
 
                    if ((bindingFlags & BindingFlags.GetProperty) != 0) 
                        // "Can not specify both SetField and GetProperty."
                        throw new ArgumentException(Environment.GetResourceString("Arg_FldSetPropGet"),"bindingFlags"); 

                    if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
                        // "Can not specify Set on a Field and Invoke on a method."
                        throw new ArgumentException(Environment.GetResourceString("Arg_FldSetInvoke"),"bindingFlags"); 
                }
                #endregion 
 
                #region Lookup Field
                FieldInfo selFld = null; 
                FieldInfo[] flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[];

                ASSERT.CONSISTENCY_CHECK(flds != null);
 
                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 || 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 1); 
                    finalists = new MethodInfo[results.Count];
                    results.CopyTo(finalists);
                }
                #endregion 
            }
            #endregion 
 
            ASSERT.CONSISTENCY_CHECK(LOGIC.IMPLIES(finalists != null, finalist != null));
 
            #region BindingFlags.GetProperty or BindingFlags.SetProperty
            if (finalist == null && isGetProperty || isSetProperty)
            {
                #region Lookup Property 
                PropertyInfo[] semiFinalists = GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[];
                ArrayList 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 (!FilterApplyMethodBaseInfo(semiFinalist, bindingFlags, null, CallingConventions.Any, new Type[argCnt], false)) 
                        continue; 

                    if (finalist == null) 
                    {
                        finalist = semiFinalist;
                    }
                    else 
                    {
                        if (results == null) 
                        { 
                            results = new ArrayList(semiFinalists.Length);
                            results.Add(finalist); 
                        }

                        results.Add(semiFinalist);
                    } 
                }
 
                if (results != null) 
                {
                    ASSERT.CONSISTENCY_CHECK(results.Count > 1); 
                    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 = new Object[0];
 
                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); 
        } 
        #endregion
 
        #endregion

        #region Object Overrides
        public override bool Equals(object obj) 
        {
            // ComObjects are identified by the instance of the Type object and not the TypeHandle. 
            return obj == this; 
        }
 
        public override int GetHashCode()
        {
            #if WIN32
                return (int)GetTypeHandleInternal().Value; 
            #else
                long l = (long)GetTypeHandleInternal().Value; 
                return unchecked((int)l); 
            #endif
        } 

        public override String ToString()
        {
            return Cache.GetToString(); 
        }
        #endregion 
 
        #region ICloneable
        public Object Clone() 
        {
            return this;
        }
        #endregion 

        #region ISerializable 
        public void GetObjectData(SerializationInfo info, StreamingContext context) 
        {
            if (info==null) 
                throw new ArgumentNullException("info");

            UnitySerializationHolder.GetUnitySerializationInfo(info, this);
        } 
        #endregion
 
        #region ICustomAttributeProvider 
        public override Object[] GetCustomAttributes(bool inherit)
        { 
            return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType, inherit);
        }

        public override Object[] GetCustomAttributes(Type attributeType, bool inherit) 
        {
            if (attributeType == null) 
                throw new ArgumentNullException("attributeType"); 

            RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; 

            if (attributeRuntimeType == null)
                throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
 
            return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit);
        } 
 
        public override bool IsDefined(Type attributeType, bool inherit)
        { 
            if (attributeType == null)
                throw new ArgumentNullException("attributeType");

            RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; 

            if (attributeRuntimeType == null) 
                throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType"); 

            return CustomAttribute.IsDefined(this, attributeRuntimeType, inherit); 
        }
        #endregion

        #region MemberInfo Overrides 
        public override String Name
        { 
            get 
            {
                return Cache.GetName(); 
            }
        }

        public override MemberTypes MemberType 
        {
            get 
            { 
                if (this.IsPublic || this.IsNotPublic)
                    return MemberTypes.TypeInfo; 
                else
                    return MemberTypes.NestedType;
            }
        } 

        public override Type DeclaringType 
        { 
            get
            { 
                return Cache.GetEnclosingType();
            }
        }
 
        public override Type ReflectedType
        { 
            get 
            {
                return DeclaringType; 
            }
        }

        public override int MetadataToken 
        {
            get 
            { 
                return m_handle.GetToken();
            } 
        }
        #endregion

        #region Legacy Internal 
        internal void CreateInstanceCheckThis()
        { 
            if (this is ReflectionOnlyType) 
                throw new ArgumentException(Environment.GetResourceString("Arg_ReflectionOnlyInvoke"));
 
            if (ContainsGenericParameters)
                throw new ArgumentException(
                    String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Acc_CreateGenericEx"), this));
 
            Type elementType = this.GetRootElementType();
 
            if (elementType == typeof(ArgIterator)) 
                throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Acc_CreateArgIterator")));
 
            if (elementType == typeof(void))
                throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Acc_CreateVoid")));
        }
 
        internal Object CreateInstanceImpl(
            BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) 
        { 
            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(null != activationAttributes)
                    {
                        ActivationServices.PushActivationAttributes(this, activationAttributes); 
                    }
 
                    if (args == null) 
                        args = new Object[0];
 
                    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
                    if (argCnt == 0 && (bindingAttr & BindingFlags.Public) != 0 && (bindingAttr & BindingFlags.Instance) != 0 
                        && (IsGenericCOMObjectImpl() || IsSubclassOf(typeof(ValueType))))
                    {
                            server = CreateInstanceImpl(((bindingAttr & BindingFlags.NonPublic) != 0) ? false : true);
                    } 
                    else
                    { 
                        MethodBase[] candidates = GetConstructors(bindingAttr); 
                        ArrayList matches = new ArrayList(candidates.Length);
                        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 ++)
                        {
                            MethodBase canidate = candidates[i];
 
                            if (FilterApplyMethodBaseInfo(
                                candidates[i], bindingAttr, null, CallingConventions.Any, argsType, false)) 
                                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
                            if(null != activationAttributes) 
                            {
                                ActivationServices.PopActivationAttributes(this);
                                activationAttributes = null;
                            } 
                            throw new MissingMethodException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("MissingConstructor_Name"), FullName));
                        } 
 
                        // It would be strange to have an argCnt of 0 and more than
                        //  one constructor. 
                        if (argCnt == 0 && cons.Length == 1 && (bindingAttr & BindingFlags.OptionalParamBinding) == 0)
                            server = Activator.CreateInstance(this, true);
                        else
                        { 
                            //      MethodBase invokeMethod = binder.BindToMethod(cons,args,null,null,culture);
                            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)
                            {
                                // Null out activation attributes before throwing exception 
                                if(null != activationAttributes)
                                { 
                                    ActivationServices.PopActivationAttributes(this); 
                                    activationAttributes = null;
                                } 
                                throw new MissingMethodException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("MissingConstructor_Name"), FullName));
                            }

                            // If we're creating a delegate, we're about to call a 
                            // constructor taking an integer to represent a target
                            // method. Since this is very difficult (and expensive) 
                            // to verify, we're just going to demand UnmanagedCode 
                            // permission before allowing this. Partially trusted
                            // clients can instead use Delegate.CreateDelegate, 
                            // which allows specification of the target method via
                            // name or MethodInfo.
                            //if (isDelegate)
                            if (typeof(Delegate).IsAssignableFrom(invokeMethod.DeclaringType)) 
                                new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
 
                            server = ((ConstructorInfo) invokeMethod).Invoke(bindingAttr,binder,args,culture); 
                            if (state != null)
                                binder.ReorderArgumentArray(ref args, state); 
                        }
                    }
                }
                finally 
                {
                    // Reset the TLS to null 
                    if(null != activationAttributes) 
                    {
                          ActivationServices.PopActivationAttributes(this); 
                          activationAttributes = null;
                    }
                }
            } 
            catch (Exception)
            { 
                throw; 
            }
 
            //Console.WriteLine(server);
            return server;
        }
 
        // the cache entry
        class ActivatorCacheEntry 
        { 
            // the type to cache
            internal Type m_type; 
            // the delegate containing the call to the ctor, will be replaced by an IntPtr to feed a calli with
            internal CtorDelegate m_ctor;
            internal RuntimeMethodHandle m_hCtorMethodHandle;
            // Is a security check needed before this constructor is invoked? 
            internal bool m_bNeedSecurityCheck;
            // Lazy initialization was performed 
            internal bool m_bFullyInitialized; 

            internal ActivatorCacheEntry(Type t, RuntimeMethodHandle rmh, bool bNeedSecurityCheck) 
            {
                m_type = t;
                m_bNeedSecurityCheck = bNeedSecurityCheck;
                m_hCtorMethodHandle = rmh; 
            }
        } 
 
        //ActivatorCache
        class ActivatorCache 
        {
            const int CACHE_SIZE = 16;
            int hash_counter; //Counter for wrap around
            ActivatorCacheEntry[] cache = new ActivatorCacheEntry[CACHE_SIZE]; 

            ConstructorInfo     delegateCtorInfo; 
            PermissionSet       delegateCreatePermissions; 

            private void InitializeDelegateCreator() { 
                // No synchronization needed here. In the worst case we create extra garbage
                PermissionSet ps = new PermissionSet(PermissionState.None);
                ps.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.MemberAccess));
                ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode)); 
                System.Threading.Thread.MemoryBarrier();
                delegateCreatePermissions = ps; 
 
                ConstructorInfo ctorInfo = typeof(CtorDelegate).GetConstructor(new Type[] {typeof(Object), typeof(IntPtr)});
                System.Threading.Thread.MemoryBarrier(); 
                delegateCtorInfo = ctorInfo; // this assignment should be last
            }

            private void InitializeCacheEntry(ActivatorCacheEntry ace) 
            {
                if (!ace.m_type.IsValueType) 
                { 
                    BCLDebug.Assert(!ace.m_hCtorMethodHandle.Equals(RuntimeMethodHandle.EmptyHandle), "Expected the default ctor method handle for a reference type.");
 
                    if (delegateCtorInfo == null)
                        InitializeDelegateCreator();
                    delegateCreatePermissions.Assert();
 
                    // No synchronization needed here. In the worst case we create extra garbage
                    CtorDelegate ctor = (CtorDelegate)delegateCtorInfo.Invoke(new Object[] {null, ace.m_hCtorMethodHandle.GetFunctionPointer()}); 
                    System.Threading.Thread.MemoryBarrier(); 
                    ace.m_ctor = ctor;
                } 
                ace.m_bFullyInitialized = true;
            }

            internal ActivatorCacheEntry GetEntry(Type t) 
            {
                int index = hash_counter; 
                for(int i = 0; i < CACHE_SIZE; i++) 
                {
                    ActivatorCacheEntry ace = cache[index]; 
                    if (ace != null && (Object)ace.m_type == (Object)t) //check for type match..
                    {
                        if (!ace.m_bFullyInitialized)
                            InitializeCacheEntry(ace); 
                        return ace;
                    } 
                    index = (index+1)&(ActivatorCache.CACHE_SIZE-1); 
                }
                return null; 
            }

            internal void SetEntry(ActivatorCacheEntry ace)
            { 
                // fill the the array backwards to hit the most recently filled entries first in GetEntry
                int index = (hash_counter-1)&(ActivatorCache.CACHE_SIZE-1); 
                hash_counter = index; 
                cache[index] = ace;
            } 
        }

        static ActivatorCache s_ActivatorCache;
 
        // the slow path of CreateInstanceImpl
        private Object CreateInstanceSlow(bool publicOnly, bool fillCache) 
        { 
            RuntimeMethodHandle runtime_ctor = RuntimeMethodHandle.EmptyHandle;
            bool bNeedSecurityCheck = true; 
            bool bCanBeCached = false;
            bool bSecurityCheckOff = false;

            CreateInstanceCheckThis(); 

            if (!fillCache) 
                bSecurityCheckOff = true; 

            Object instance = RuntimeTypeHandle.CreateInstance(this, publicOnly, bSecurityCheckOff, ref bCanBeCached, ref runtime_ctor, ref bNeedSecurityCheck); 

            if (bCanBeCached && fillCache)
            {
                ActivatorCache activatorCache = s_ActivatorCache; 
                if(activatorCache == null)
                { 
                    // No synchronization needed here. In the worst case we create extra garbage 
                    activatorCache = new ActivatorCache();
                    System.Threading.Thread.MemoryBarrier(); 
                    s_ActivatorCache = activatorCache;
                }

                // cache the ctor 
                ActivatorCacheEntry ace = new ActivatorCacheEntry(this, runtime_ctor, bNeedSecurityCheck);
                System.Threading.Thread.MemoryBarrier(); 
                activatorCache.SetEntry(ace); 
            }
            return instance; 
        }

        [DebuggerStepThroughAttribute]
        [Diagnostics.DebuggerHidden] 
        internal Object CreateInstanceImpl(bool publicOnly)
        { 
            return CreateInstanceImpl(publicOnly, false, true); 
        }
 
        [DebuggerStepThroughAttribute]
        [Diagnostics.DebuggerHidden]
        internal Object CreateInstanceImpl(bool publicOnly, bool skipVisibilityChecks, bool fillCache)
        { 
            // next line will throw for ReflectionOnly types
            RuntimeTypeHandle typeHandle = TypeHandle; 
            ActivatorCache activatorCache = s_ActivatorCache; 
            if (activatorCache != null)
            { 
                ActivatorCacheEntry ace = activatorCache.GetEntry(this);
                if (ace != null)
                {
                    if (publicOnly) 
                    {
                        if (ace.m_ctor != null && 
                            (ace.m_hCtorMethodHandle.GetAttributes() & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) 
                        {
                            throw new MissingMethodException(Environment.GetResourceString("Arg_NoDefCTor")); 
                        }
                    }

                    // Allocate empty object 
                    Object instance = typeHandle.Allocate();
                    if (ace.m_ctor != null) 
                    { 
                        // Perform security checks if needed
                        if (!skipVisibilityChecks && ace.m_bNeedSecurityCheck) 
                        {
                            MethodBase.PerformSecurityCheck(instance, ace.m_hCtorMethodHandle, TypeHandle.Value, INVOCATION_FLAGS_CONSTRUCTOR_INVOKE);
                        }
                        // Call ctor (value types wont have any) 
                        try
                        { 
                            ace.m_ctor(instance); 
                        }
                        catch (Exception e) 
                        {
                            throw new TargetInvocationException(e);
                        }
                    } 
                    return instance;
                } 
            } 
            return CreateInstanceSlow(publicOnly, fillCache);
        } 

    //End

        internal bool SupportsInterface(Object o) 
        {
            return TypeHandle.SupportsInterface(o); 
        } 

        internal void InvalidateCachedNestedType() 
        {
            Cache.InvalidateCachedNestedType();
        }
 
        internal bool IsGenericCOMObjectImpl()
        { 
            return m_handle.IsComObject(true); 
        }
        #endregion 

        #region Legacy Static Internal
        internal static bool CanCastTo(RuntimeType fromType, RuntimeType toType)
        { 
            return fromType.GetTypeHandleInternal().CanCastTo(toType.GetTypeHandleInternal());
        } 
 
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private static extern Object _CreateEnum(IntPtr enumType, long value); 
        internal static Object CreateEnum(RuntimeTypeHandle enumType, long value) {
            return _CreateEnum(enumType.Value, value);
        }
 
#if FEATURE_COMINTEROP
        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        private extern Object InvokeDispMethod( 
            String name, BindingFlags invokeAttr, Object target, Object[] args,
            bool[] byrefModifiers, int culture, String[] namedParameters); 

        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal static extern Type GetTypeFromProgIDImpl(String progID, String server, bool throwOnError);
 
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal static extern Type GetTypeFromCLSIDImpl(Guid clsid, String server, bool throwOnError); 
#endif 

        internal static Type PrivateGetType(String typeName, bool throwOnError, bool ignoreCase, 
            ref StackCrawlMark stackMark)
        {
            return PrivateGetType(typeName, throwOnError, ignoreCase, false, ref stackMark);
        } 

        internal static Type PrivateGetType(String typeName, bool throwOnError, bool ignoreCase, bool reflectionOnly, 
            ref StackCrawlMark stackMark) 
        {
            unsafe 
            {
                if (typeName == null)
                    throw new ArgumentNullException("TypeName");
 
                return RuntimeTypeHandle.GetTypeByName(
                    typeName, throwOnError, ignoreCase, reflectionOnly, ref stackMark).GetRuntimeType(); 
            } 
        }
 
        #endregion

        #region COM
#if FEATURE_COMINTEROP 
        private Object ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, int[] aWrapperTypes, ref MessageData msgData)
        { 
            ParameterModifier[] aParamMod = null; 
            Object ret = null;
 
            // Allocate a new message
            Message reqMsg = new Message();
            reqMsg.InitFields(msgData);
 
            // Retrieve the required information from the message object.
            MethodInfo meth = (MethodInfo)reqMsg.GetMethodBase(); 
            Object[] aArgs = reqMsg.Args; 
            int cArgs = aArgs.Length;
 
            // Retrieve information from the method we are invoking on.
            ParameterInfo[] aParams = meth.GetParametersNoCopy();

            // If we have arguments, then set the byref flags to true for byref arguments. 
            // We also wrap the arguments that require wrapping.
            if (cArgs > 0) 
            { 
                ParameterModifier paramMod = new ParameterModifier(cArgs);
                for (int i = 0; i < cArgs; i++) 
                {
                    if (aParams[i].ParameterType.IsByRef)
                        paramMod[i] = true;
                } 

                aParamMod = new ParameterModifier[1]; 
                aParamMod[0] = paramMod; 

                if (aWrapperTypes != null) 
                    WrapArgsForInvokeCall(aArgs, aWrapperTypes);
            }

            // If the method has a void return type, then set the IgnoreReturn binding flag. 
            if (meth.ReturnType == typeof(void))
                flags |= BindingFlags.IgnoreReturn; 
 
            try
            { 
                // Invoke the method using InvokeMember().
                ret = InvokeMember(memberName, flags, null, target, aArgs, aParamMod, null, null);
            }
            catch (TargetInvocationException e) 
            {
                // For target invocation exceptions, we need to unwrap the inner exception and 
                // re-throw it. 
                throw e.InnerException;
            } 

            // Convert each byref argument that is not of the proper type to
            // the parameter type using the OleAutBinder.
            for (int i = 0; i < cArgs; i++) 
            {
                if (aParamMod[0][i] && aArgs[i] != null) 
                { 
                    // The parameter is byref.
                    Type paramType = aParams[i].ParameterType.GetElementType(); 
                    if (paramType != aArgs[i].GetType())
                        aArgs[i] = ForwardCallBinder.ChangeType(aArgs[i], paramType, null);
                }
            } 

            // If the return type is not of the proper type, then convert it 
            // to the proper type using the OleAutBinder. 
            if (ret != null)
            { 
                Type retType = meth.ReturnType;
                if (retType != ret.GetType())
                    ret = ForwardCallBinder.ChangeType(ret, retType, null);
            } 

            // Propagate the out parameters 
            RealProxy.PropagateOutParameters(reqMsg, aArgs, ret); 

            // Return the value returned by the InvokeMember call. 
            return ret;
        }

        private void WrapArgsForInvokeCall(Object[] aArgs, int[] aWrapperTypes) 
        {
            int cArgs = aArgs.Length; 
            for (int i = 0; i < cArgs; i++) 
            {
                if (aWrapperTypes[i] == 0) 
                    continue;

                if (((DispatchWrapperType)aWrapperTypes[i] & DispatchWrapperType.SafeArray) != 0)
                { 
                    Type wrapperType = null;
                    bool isString = false; 
 
                    // Determine the type of wrapper to use.
                    switch ((DispatchWrapperType)aWrapperTypes[i] & ~DispatchWrapperType.SafeArray) 
                    {
                        case DispatchWrapperType.Unknown:
                            wrapperType = typeof(UnknownWrapper);
                            break; 
                        case DispatchWrapperType.Dispatch:
                            wrapperType = typeof(DispatchWrapper); 
                            break; 
                        case DispatchWrapperType.Error:
                            wrapperType = typeof(ErrorWrapper); 
                            break;
                        case DispatchWrapperType.Currency:
                            wrapperType = typeof(CurrencyWrapper);
                            break; 
                        case DispatchWrapperType.BStr:
                            wrapperType = typeof(BStrWrapper); 
                            isString = true; 
                            break;
                        default: 
                            BCLDebug.Assert(false, "[RuntimeType.WrapArgsForInvokeCall]Invalid safe array wrapper type specified.");
                            break;
                    }
 
                    // Allocate the new array of wrappers.
                    Array oldArray = (Array)aArgs[i]; 
                    int numElems = oldArray.Length; 
                    Object[] newArray = (Object[])Array.CreateInstance(wrapperType, numElems);
 
                    // Retrieve the ConstructorInfo for the wrapper type.
                    ConstructorInfo wrapperCons;
                    if(isString)
                    { 
                         wrapperCons = wrapperType.GetConstructor(new Type[] {typeof(String)});
                    } 
                    else 
                    {
                         wrapperCons = wrapperType.GetConstructor(new Type[] {typeof(Object)}); 
                    }

                    // Wrap each of the elements of the array.
                    for (int currElem = 0; currElem < numElems; currElem++) 
                    {
                        if(isString) 
                        { 
                            newArray[currElem] = wrapperCons.Invoke(new Object[] {(String)oldArray.GetValue(currElem)});
                        } 
                        else
                        {
                            newArray[currElem] = wrapperCons.Invoke(new Object[] {oldArray.GetValue(currElem)});
                        } 
                    }
 
                    // Update the argument. 
                    aArgs[i] = newArray;
                } 
                else
                {
                    // Determine the wrapper to use and then wrap the argument.
                    switch ((DispatchWrapperType)aWrapperTypes[i]) 
                    {
                        case DispatchWrapperType.Unknown: 
                            aArgs[i] = new UnknownWrapper(aArgs[i]); 
                            break;
                        case DispatchWrapperType.Dispatch: 
                            aArgs[i] = new DispatchWrapper(aArgs[i]);
                            break;
                        case DispatchWrapperType.Error:
                            aArgs[i] = new ErrorWrapper(aArgs[i]); 
                            break;
                        case DispatchWrapperType.Currency: 
                            aArgs[i] = new CurrencyWrapper(aArgs[i]); 
                            break;
                        case DispatchWrapperType.BStr: 
                            aArgs[i] = new BStrWrapper((String)aArgs[i]);
                            break;
                        default:
                            BCLDebug.Assert(false, "[RuntimeType.WrapArgsForInvokeCall]Invalid wrapper type specified."); 
                            break;
                    } 
                } 
            }
        } 

        private OleAutBinder ForwardCallBinder
        {
            get 
            {
                // Synchronization is not required. 
                if (s_ForwardCallBinder == null) 
                    s_ForwardCallBinder = new OleAutBinder();
 
                return s_ForwardCallBinder;
            }
        }
 
        [Flags]
        private enum DispatchWrapperType : int 
        { 
            // This enum must stay in [....] with the DispatchWrapperType enum defined in MLInfo.h
            Unknown         = 0x00000001, 
            Dispatch        = 0x00000002,
            Record          = 0x00000004,
            Error           = 0x00000008,
            Currency        = 0x00000010, 
            BStr            = 0x00000020,
            SafeArray       = 0x00010000 
        } 

        private static OleAutBinder s_ForwardCallBinder; 
#endif // FEATURE_COMINTEROP
        #endregion
    }
 
    // this is the introspection only type. This type overrides all the functions with runtime semantics
    // and throws an exception. 
    // The idea behind this type is that it relieves RuntimeType from doing honerous checks about ReflectionOnly 
    // context.
    // This type should not derive from RuntimeType but it's doing so for convinience. 
    // That should not present a security threat though it is risky as a direct call to one of the base method
    // method (RuntimeType) and an instance of this type will work around the reason to have this type in the
    // first place. However given RuntimeType is not public all its methods are protected and require full trust
    // to be accessed 
    [Serializable()]
    internal class ReflectionOnlyType : RuntimeType { 
 
        private ReflectionOnlyType() {}
 
       // always throw
        public override RuntimeTypeHandle TypeHandle
        {
            get 
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly")); 
            } 
        }
 
    }

    namespace Reflection
    { 
        [Serializable]
        internal sealed class CerArrayList 
        { 
            private const int MinSize = 4;
 
            private V[] m_array;
            private int m_count;

            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
            internal CerArrayList(List list)
            { 
                m_array = new V[list.Count]; 
                for (int i = 0; i < list.Count; i ++)
                    m_array[i] = list[i]; 
                m_count = list.Count;
            }

            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
            internal CerArrayList(int length)
            { 
                if (length < MinSize) 
                    length = MinSize;
 
                m_array = new V[length];
                m_count = 0;
            }
 
            internal int Count
            { 
                [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
                get { return m_count; }
            } 

            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
            internal void Preallocate(int addition)
            { 
                if (m_array.Length - m_count > addition)
                    return; 
 
                int newSize = m_array.Length * 2 > m_array.Length + addition ? m_array.Length * 2 : m_array.Length + addition;
 
                V[] newArray = new V[newSize];

                for (int i = 0; i < m_count; i++)
                { 
                    newArray[i] = m_array[i];
                } 
 
                m_array = newArray;
            } 

            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
            internal void Add(V value) { m_array[m_count] = value; m_count++; }
 
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
            internal void Replace(int index, V value) 
            { 
                if (index >= m_count)
                    throw new InvalidOperationException(); 

                m_array[index] = value;
            }
 
            internal V this[int index]
            { 
                [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
                get { return m_array[index]; }
            } 
        }

        [Serializable]
        internal sealed class CerHashtable 
        {
            private K[] m_key; 
            private V[] m_value; 
            private int m_count;
 
            private const int MinSize = 7;

            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
            internal CerHashtable() : this(MinSize) { } 

            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
            internal CerHashtable(int size) 
            {
                size = HashHelpers.GetPrime(size); 
                m_key = new K[size];
                m_value = new V[size];
            }
 
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
            internal void Preallocate(int count) 
            { 
                bool tookLock = false;
                bool success = false; 
                K[] newKeys = null;;
                V[] newValues = null;
                RuntimeHelpers.PrepareConstrainedRegions();
                try { 
                    Monitor.ReliableEnter(this, ref tookLock);
                    int newSize = (count + m_count) * 2; 
 
                    if (newSize < m_value.Length)
                        return; 

                    newSize = HashHelpers.GetPrime(newSize);

                    newKeys = new K[newSize]; 
                    newValues = new V[newSize];
 
                    for (int i = 0; i < m_key.Length; i++) 
                    {
                        K key = m_key[i]; 

                        if (key != null)
                        {
                            int dummyCount = 0; 
                            Insert(newKeys, newValues, ref dummyCount, key, m_value[i]);
                        } 
                    } 

                    success = true; 
                }
                finally {
                    if (success)
                    { 
                        m_key = newKeys;
                        m_value = newValues; 
                    } 

                    if (tookLock) 
                        Monitor.Exit(this);
                }
            }
 
            // Written as a static so we can share this code from Set and
            // Preallocate, which adjusts the data structure in place. 
            // Returns whether we inserted the item into a new slot or reused 
            // an existing hash table bucket.
            // Reliability-wise, we don't guarantee that the updates to the key 
            // and value arrays are done atomically within a CER.  Either
            // add your own CER or use temporary copies of this data structure.
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
            private static void Insert(K[] keys, V[] values, ref int count, K key, V value) 
            {
                int hashcode = key.GetHashCode(); 
                if (hashcode < 0) 
                    hashcode = -hashcode;
                int firstIndex = hashcode % keys.Length; 
                int index = firstIndex;

                while (true)
                { 
                    K hit = keys[index];
 
                    if ((object)hit == null) 
                    {
                        RuntimeHelpers.PrepareConstrainedRegions(); 
                        try { }
                        finally
                        {
                            keys[index] = key; 
                            values[index] = value;
                            count++; 
                        } 

                        break; 
                    }
                    else if (hit.Equals(key))  // Replace existing item
                    {
                        //BCLDebug.Assert(false, "Key was already in CerHashtable!  Potential ---- (or bug) in the Reflection cache?"); 
                        throw new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicate__", hit, key));
                        // If we wanted to make this more general, do this: 
                        /* 
                        values[index] = value;
                        usedNewSlot = false; 
                        */
                        //break;
                    }
                    else 
                    {
                        index++; 
                        index %= keys.Length; 
                    }
                } 
            }

            internal V this[K key]
            { 
                [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
                set 
                { 
                    bool tookLock = false;
                    RuntimeHelpers.PrepareConstrainedRegions(); 
                    try
                    {
                        Monitor.ReliableEnter(this, ref tookLock);
                        Insert(m_key, m_value, ref m_count, key, value); 
                    }
                    finally 
                    { 
                        if (tookLock)
                            Monitor.Exit(this); 
                    }
                }
                [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
                get 
                {
                    bool tookLock = false; 
 
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try 
                    {
                        Monitor.ReliableEnter(this, ref tookLock);

                        int hashcode = key.GetHashCode(); 
                        if (hashcode < 0)
                            hashcode = -hashcode; 
                        int firstIndex = hashcode % m_key.Length; 
                        int index = firstIndex;
 
                        while (true)
                        {
                            K hit = m_key[index];
 
                            if ((object)hit != null)
                            { 
                                if (hit.Equals(key)) 
                                    return m_value[index];
 
                                index++;
                                index %= m_key.Length;
                            }
                            else 
                            {
                                return default(V); 
                            } 
                        }
                    } 
                    finally
                    {
                        if (tookLock)
                            Monitor.Exit(this); 
                    }
 
                } 
            }
        } 
    }

    #region Library
    internal unsafe struct Utf8String 
    {
        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        private static extern unsafe bool EqualsCaseSensitive(void* szLhs, void* szRhs, int cSz); 

        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        private static extern unsafe bool EqualsCaseInsensitive(void* szLhs, void* szRhs, int cSz);

        private static int GetUtf8StringByteLength(void* pUtf8String)
        { 
            int len = 0;
 
            unsafe 
            {
                byte * pItr = (byte*)pUtf8String; 

                while (*pItr != 0)
                {
                    len++; 
                    pItr++;
                } 
            } 

            return len; 
        }

        private void* m_pStringHeap;        // This is the raw UTF8 string.
        private int m_StringHeapByteLength; 

        internal Utf8String(void* pStringHeap) 
        { 
            m_pStringHeap = pStringHeap;
            if (pStringHeap != null) 
            {
                m_StringHeapByteLength = GetUtf8StringByteLength(pStringHeap);
            }
            else 
            {
                m_StringHeapByteLength = 0; 
            } 
        }
 
        internal unsafe Utf8String(void* pUtf8String, int cUtf8String)
        {
              m_pStringHeap = pUtf8String;
              m_StringHeapByteLength = cUtf8String; 
        }
 
        internal unsafe bool Equals(Utf8String s) 
        {
            if (m_pStringHeap == null) 
            {
                return s.m_StringHeapByteLength == 0;
            }
            if ((s.m_StringHeapByteLength == m_StringHeapByteLength) && (m_StringHeapByteLength != 0)) 
            {
                return Utf8String.EqualsCaseSensitive(s.m_pStringHeap, m_pStringHeap, m_StringHeapByteLength); 
            } 
            return false;
        } 

        internal unsafe bool EqualsCaseInsensitive(Utf8String s)
        {
              if (m_pStringHeap == null) 
              {
                    return s.m_StringHeapByteLength == 0; 
              } 
              if ((s.m_StringHeapByteLength == m_StringHeapByteLength) && (m_StringHeapByteLength != 0))
              { 
                    return Utf8String.EqualsCaseInsensitive(s.m_pStringHeap, m_pStringHeap, m_StringHeapByteLength);
              }
              return false;
        } 

        public override string ToString() 
        { 
            unsafe
            { 
                byte* buf = stackalloc byte[m_StringHeapByteLength];
                byte * pItr = (byte*)m_pStringHeap;

                for (int currentPos = 0; currentPos < m_StringHeapByteLength; currentPos++) 
                {
                    buf[currentPos] = *pItr; 
                    pItr++; 
                }
 
                if (m_StringHeapByteLength == 0)
                    return "";

                int cResult = Encoding.UTF8.GetCharCount(buf, m_StringHeapByteLength); 
                char* result = stackalloc char[cResult];
                Encoding.UTF8.GetChars(buf, m_StringHeapByteLength, result, cResult); 
                return new string(result, 0, cResult); 
            }
        } 
    }

    internal sealed class ASSERT : Exception
    { 
        #region FRIEND
        private static bool AssertIsFriend(Type[] friends, StackTrace st) 
        { 
            Type typeOfCallee = st.GetFrame(1).GetMethod().DeclaringType;
            Type typeOfCaller = st.GetFrame(2).GetMethod().DeclaringType; 

            bool noFriends = true;
            foreach(Type friend in friends)
            { 
                if (typeOfCaller != friend && typeOfCaller != typeOfCallee)
                    noFriends = false; 
            } 

            if (noFriends) 
                Assert(false, Environment.GetResourceString("RtType.InvalidCaller"), st.ToString());

            return true;
        } 
        [Conditional("_DEBUG")]
        internal static void FRIEND(Type[] friends) 
        { 
            StackTrace st = new StackTrace();
            AssertIsFriend(friends, st); 
        }
        [Conditional("_DEBUG")]
        internal static void FRIEND(Type friend)
        { 
            StackTrace st = new StackTrace();
            AssertIsFriend(new Type[] {friend}, st); 
        } 
        [Conditional("_DEBUG")]
        internal static void FRIEND(string ns) 
        {
            StackTrace st = new StackTrace();
            string nsOfCallee = st.GetFrame(1).GetMethod().DeclaringType.Namespace;
            string nsOfCaller = st.GetFrame(2).GetMethod().DeclaringType.Namespace; 
            Assert(nsOfCaller.Equals(nsOfCaller) || nsOfCaller.Equals(ns), Environment.GetResourceString("RtType.InvalidCaller"), st.ToString());
        } 
        #endregion 

        #region PRECONDITION 
        [Conditional("_DEBUG")]
        internal static void PRECONDITION(bool condition)
        {
            Assert(condition); 
        }
 
        [Conditional("_DEBUG")] 
        internal static void PRECONDITION(bool condition, string message)
        { 
            Assert(condition, message);
        }

        [Conditional("_DEBUG")] 
        internal static void PRECONDITION(bool condition, string message, string detailedMessage)
        { 
            Assert(condition, message, detailedMessage); 
        }
        #endregion 

        #region POSTCONDITION
        [Conditional("_DEBUG")]
        internal static void POSTCONDITION(bool condition) 
        {
            Assert(condition); 
        } 

        [Conditional("_DEBUG")] 
        internal static void POSTCONDITION(bool condition, string message)
        {
            Assert(condition, message);
        } 

        [Conditional("_DEBUG")] 
        internal static void POSTCONDITION(bool condition, string message, string detailedMessage) 
        {
            Assert(condition, message, detailedMessage); 
        }
        #endregion

        #region CONSISTENCY_CHECK 
        [Conditional("_DEBUG")]
        internal static void CONSISTENCY_CHECK(bool condition) 
        { 
            Assert(condition);
        } 

        [Conditional("_DEBUG")]
        internal static void CONSISTENCY_CHECK(bool condition, string message)
        { 
            Assert(condition, message);
        } 
 
        [Conditional("_DEBUG")]
        internal static void CONSISTENCY_CHECK(bool condition, string message, string detailedMessage) 
        {
            Assert(condition, message, detailedMessage);
        }
        #endregion 

        #region SIMPLIFYING_ASSUMPTION 
        [Conditional("_DEBUG")] 
        internal static void SIMPLIFYING_ASSUMPTION(bool condition)
        { 
            Assert(condition);
        }

        [Conditional("_DEBUG")] 
        internal static void SIMPLIFYING_ASSUMPTION(bool condition, string message)
        { 
            Assert(condition, message); 
        }
 
        [Conditional("_DEBUG")]
        internal static void SIMPLIFYING_ASSUMPTION(bool condition, string message, string detailedMessage)
        {
            Assert(condition, message, detailedMessage); 
        }
        #endregion 
 
        #region UNREACHABLE
        [Conditional("_DEBUG")] 
        internal static void UNREACHABLE()
        {
            Assert();
        } 

        [Conditional("_DEBUG")] 
        internal static void UNREACHABLE(string message) 
        {
            Assert(message); 
        }

        [Conditional("_DEBUG")]
        internal static void UNREACHABLE(string message, string detailedMessage) 
        {
            Assert(message, detailedMessage); 
        } 
        #endregion
 
        #region NOT_IMPLEMENTED
        [Conditional("_DEBUG")]
        internal static void NOT_IMPLEMENTED()
        { 
            Assert();
        } 
 
        [Conditional("_DEBUG")]
        internal static void NOT_IMPLEMENTED(string message) 
        {
            Assert(message);
        }
 
        [Conditional("_DEBUG")]
        internal static void NOT_IMPLEMENTED(string message, string detailedMessage) 
        { 
            Assert(message, detailedMessage);
        } 
        #endregion

        #region Private Asserts - Throw before assert so debugger can inspect
        private static void Assert() 
        {
            Assert(false, null, null); 
        } 

        private static void Assert(string message) 
        {
            Assert(false, message, null);
        }
 
        private static void Assert(bool condition)
        { 
            Assert(condition, null, null); 
        }
 
        private static void Assert(bool condition, string message)
        {
            Assert(condition, message, null);
        } 

        private static void Assert(string message, string detailedMessage) 
        { 
            Assert(false, message, detailedMessage);
        } 

        private static void Assert(bool condition, string message, string detailedMessage)
        {
            if (!condition) 
            {
//                Console.WriteLine("ASSERT MESSAGE: " + message + ", " + detailedMessage); 
//                System.Diagnostics.Debug.Assert(condition, message, detailedMessage); 
//                throw new ASSERT();
            } 
        }
        #endregion
    }
    internal static class LOGIC 
    {
        internal static bool IMPLIES(bool p, bool q) 
        { 
            return !p || q;
        } 

        internal static bool BIJECTION(bool p, bool q)
        {
            return IMPLIES(p,q) && IMPLIES(q,p); 
        }
    } 
    #endregion 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK