//---------------------------------------------------------------------
//  This file is part of the CLR Managed Debugger (mdbg) Sample.
// 
//  Copyright (C) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------------
using System;
using System.Reflection;
using System.Text;
using System.Runtime.InteropServices;
using System.Globalization;
using System.Diagnostics;

// NOTE: For MDBG_FAKE_COM we compile this file by itself into a .dll, disassemble to IL, and then strip 
// the assembly header out and include the il along with the others in the interop assembly
namespace Microsoft.Samples.Debugging.CorMetadata.NativeApi
{

    // GUID Copied from Cor.h
    [Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44"),
     InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
    ] // IID_IMetadataImport from cor.h

    // This should be a private interface, but
    // we cannot do that becuase we are then getting an exception
    // "The specified type must be visible from COM." @ CorMetadataImport::GetRawInterface
    public interface IMetadataImport
    {
        //STDMETHOD_(void, CloseEnum)(HCORENUM hEnum) PURE;
        [PreserveSig]  void CloseEnum(IntPtr hEnum);
        
        //STDMETHOD(CountEnum)(HCORENUM hEnum, ULONG *pulCount) PURE;
        void CountEnum(IntPtr hEnum, [ComAliasName("ULONG*")] out int pulCount);
        
        //STDMETHOD(ResetEnum)(HCORENUM hEnum, ULONG ulPos) PURE;
        void ResetEnum(IntPtr hEnum, int ulPos);
        
        //STDMETHOD(EnumTypeDefs)(HCORENUM *phEnum, mdTypeDef rTypeDefs[],ULONG cMax, ULONG *pcTypeDefs) PURE;
        //void EnumTypeDefs(out IntPtr phEnum,int[] rTypeDefs,uint cMax, out uint pcTypeDefs);  
        void EnumTypeDefs(
                            ref IntPtr phEnum, 
                            [ComAliasName("mdTypeDef*")] out int rTypeDefs,
                            uint cMax /*must be 1*/, 
                            [ComAliasName("ULONG*")] out uint pcTypeDefs); 

#if !MDBG_FAKE_COM        
        //STDMETHOD(EnumInterfaceImpls)(HCORENUM *phEnum, mdTypeDef td, mdInterfaceImpl rImpls[], ULONG cMax, ULONG* pcImpls) PURE;
        void EnumInterfaceImpls_(IntPtr phEnum, int td);
        
        //STDMETHOD(EnumTypeRefs)(HCORENUM *phEnum, mdTypeRef rTypeRefs[], ULONG cMax, ULONG* pcTypeRefs) PURE;
        void EnumTypeRefs_();
#endif                       

        //     STDMETHOD(FindTypeDefByName)(           // S_OK or error.
        //         LPCWSTR     szTypeDef,              // [IN] Name of the Type.
        //         mdToken     tkEnclosingClass,       // [IN] TypeDef/TypeRef for Enclosing class.
        //         mdTypeDef   *ptd) PURE;             // [OUT] Put the TypeDef token here.
        void FindTypeDefByName(
                               [In, MarshalAs(UnmanagedType.LPWStr)] string szTypeDef,
                               [In] int tkEnclosingClass,
                               [ComAliasName("mdTypeDef*")] [Out] out int token
                               );
        
        //     STDMETHOD(GetScopeProps)(               // S_OK or error.
        //         LPWSTR      szName,                 // [OUT] Put the name here.
        //         ULONG       cchName,                // [IN] Size of name buffer in wide chars.
        //         ULONG       *pchName,               // [OUT] Put size of name (wide chars) here.
        //         GUID        *pmvid) PURE;           // [OUT, OPTIONAL] Put MVID here.
		void GetScopeProps(
            [Out,MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName,
            [In] int cchName,
            [ComAliasName("ULONG*")] out int pchName,
            out Guid mvid    
		);

#if !MDBG_FAKE_COM
        //     STDMETHOD(GetModuleFromScope)(          // S_OK.
        //         mdModule    *pmd) PURE;             // [OUT] Put mdModule token here.
        void GetModuleFromScope_();
#endif

        //     STDMETHOD(GetTypeDefProps)(             // S_OK or error.
        //         mdTypeDef   td,                     // [IN] TypeDef token for inquiry.
        //         LPWSTR      szTypeDef,              // [OUT] Put name here.
        //         ULONG       cchTypeDef,             // [IN] size of name buffer in wide chars.
        //         ULONG       *pchTypeDef,            // [OUT] put size of name (wide chars) here.
        //         DWORD       *pdwTypeDefFlags,       // [OUT] Put flags here.
        //         mdToken     *ptkExtends) PURE;      // [OUT] Put base class TypeDef/TypeRef here.
        void GetTypeDefProps([In] int td,
                             [Out, MarshalAs( UnmanagedType.LPWStr)] StringBuilder szTypeDef,
                             [In] int cchTypeDef,
                             [ComAliasName("ULONG*")] [Out] out int pchTypeDef,
                             [Out, MarshalAs(UnmanagedType.U4)] out System.Reflection.TypeAttributes pdwTypeDefFlags,
                             [ComAliasName("mdToken*")] [Out] out int ptkExtends
                             );

#if !MDBG_FAKE_COM
        //     STDMETHOD(GetInterfaceImplProps)(       // S_OK or error.
        //         mdInterfaceImpl iiImpl,             // [IN] InterfaceImpl token.
        //         mdTypeDef   *pClass,                // [OUT] Put implementing class token here.
        //         mdToken     *ptkIface) PURE;        // [OUT] Put implemented interface token here.
        void GetInterfaceImplProps_();
#endif

        //     STDMETHOD(GetTypeRefProps)(             // S_OK or error.
        //         mdTypeRef   tr,                     // [IN] TypeRef token.
        //         mdToken     *ptkResolutionScope,    // [OUT] Resolution scope, ModuleRef or AssemblyRef.
        //         LPWSTR      szName,                 // [OUT] Name of the TypeRef.
        //         ULONG       cchName,                // [IN] Size of buffer.
        //         ULONG       *pchName) PURE;         // [OUT] Size of Name.
        void GetTypeRefProps(
                             int tr,
                             [ComAliasName("mdToken*")] [Out] out int ptkResolutionScope,
                             [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName,
                             [In] int cchName,
                             [ComAliasName("ULONG*")] out int pchName
                             );

#if !MDBG_FAKE_COM
        //     STDMETHOD(ResolveTypeRef)(mdTypeRef tr, REFIID riid, IUnknown **ppIScope, mdTypeDef *ptd) PURE;
        void ResolveTypeRef_();

        //     STDMETHOD(EnumMembers)(                 // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdTypeDef   cl,                     // [IN] TypeDef to scope the enumeration.   
        //         mdToken     rMembers[],             // [OUT] Put MemberDefs here.   
        //         ULONG       cMax,                   // [IN] Max MemberDefs to put.  
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        void EnumMembers_();
        
        //     STDMETHOD(EnumMembersWithName)(         // S_OK, S_FALSE, or error.             
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.                
        //         mdTypeDef   cl,                     // [IN] TypeDef to scope the enumeration.   
        //         LPCWSTR     szName,                 // [IN] Limit results to those with this name.              
        //         mdToken     rMembers[],             // [OUT] Put MemberDefs here.                   
        //         ULONG       cMax,                   // [IN] Max MemberDefs to put.              
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        void EnumMembersWithName_();
#endif
        
        //     STDMETHOD(EnumMethods)(                 // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdTypeDef   cl,                     // [IN] TypeDef to scope the enumeration.   
        //         mdMethodDef rMethods[],             // [OUT] Put MethodDefs here.   
        //         ULONG       cMax,                   // [IN] Max MethodDefs to put.  
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        void EnumMethods(ref IntPtr phEnum,
                         int cl,
                         [ComAliasName("mdMethodDef*")] out int mdMethodDef,
                         int cMax, /*must be 1*/
                         [ComAliasName("ULONG*")] out int pcTokens
                         );
        
#if !MDBG_FAKE_COM
        //     STDMETHOD(EnumMethodsWithName)(         // S_OK, S_FALSE, or error.             
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.                
        //         mdTypeDef   cl,                     // [IN] TypeDef to scope the enumeration.   
        //         LPCWSTR     szName,                 // [IN] Limit results to those with this name.              
        //         mdMethodDef rMethods[],             // [OU] Put MethodDefs here.    
        //         ULONG       cMax,                   // [IN] Max MethodDefs to put.              
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        void EnumMethodsWithName_();
#endif

        //     STDMETHOD(EnumFields)(                 // S_OK, S_FALSE, or error.  
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdTypeDef   cl,                     // [IN] TypeDef to scope the enumeration.   
        //         mdFieldDef  rFields[],              // [OUT] Put FieldDefs here.    
        //         ULONG       cMax,                   // [IN] Max FieldDefs to put.   
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        //void EnumFields_();
        /*[PreserveSig]*/
        void EnumFields(ref IntPtr phEnum,
                        int cl,
                        [ComAliasName("mdFieldDef*")] out int mdFieldDef,
                        int cMax /*must be 1*/, 
                        [ComAliasName("ULONG*")] out uint pcTokens); 

        
#if !MDBG_FAKE_COM
        //     STDMETHOD(EnumFieldsWithName)(         // S_OK, S_FALSE, or error.              
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.                
        //         mdTypeDef   cl,                     // [IN] TypeDef to scope the enumeration.   
        //         LPCWSTR     szName,                 // [IN] Limit results to those with this name.              
        //         mdFieldDef  rFields[],              // [OUT] Put MemberDefs here.                   
        //         ULONG       cMax,                   // [IN] Max MemberDefs to put.              
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        void EnumFieldsWithName_();
#endif

        //     STDMETHOD(EnumParams)(                  // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdMethodDef mb,                     // [IN] MethodDef to scope the enumeration. 
        //         mdParamDef  rParams[],              // [OUT] Put ParamDefs here.    
        //         ULONG       cMax,                   // [IN] Max ParamDefs to put.   
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.
        void EnumParams(ref IntPtr phEnum,
                        int mdMethodDef,
                        [ComAliasName("mdParamDef*")] out int mdParamDef,
                        int cMax /*must be 1*/,
                        [ComAliasName("ULONG*")] out uint pcTokens);

#if !MDBG_FAKE_COM
        //     STDMETHOD(EnumMemberRefs)(              // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdToken     tkParent,               // [IN] Parent token to scope the enumeration.  
        //         mdMemberRef rMemberRefs[],          // [OUT] Put MemberRefs here.   
        //         ULONG       cMax,                   // [IN] Max MemberRefs to put.  
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        void EnumMemberRefs_();
        
        //     STDMETHOD(EnumMethodImpls)(             // S_OK, S_FALSE, or error  
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdTypeDef   td,                     // [IN] TypeDef to scope the enumeration.   
        //         mdToken     rMethodBody[],          // [OUT] Put Method Body tokens here.   
        //         mdToken     rMethodDecl[],          // [OUT] Put Method Declaration tokens here.
        //         ULONG       cMax,                   // [IN] Max tokens to put.  
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        void EnumMethodImpls_();
        
        //     STDMETHOD(EnumPermissionSets)(          // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdToken     tk,                     // [IN] if !NIL, token to scope the enumeration.    
        //         DWORD       dwActions,              // [IN] if !0, return only these actions.   
        //         mdPermission rPermission[],         // [OUT] Put Permissions here.  
        //         ULONG       cMax,                   // [IN] Max Permissions to put. 
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        void EnumPermissionSets_();
        
        //     STDMETHOD(FindMember)(  
        //         mdTypeDef   td,                     // [IN] given typedef   
        //         LPCWSTR     szName,                 // [IN] member name 
        //         PCCOR_SIGNATURE pvSigBlob,          // [IN] point to a blob value of CLR signature 
        //         ULONG       cbSigBlob,              // [IN] count of bytes in the signature blob    
        //         mdToken     *pmb) PURE;             // [OUT] matching memberdef 
        void FindMember_();
        
        //     STDMETHOD(FindMethod)(  
        //         mdTypeDef   td,                     // [IN] given typedef   
        //         LPCWSTR     szName,                 // [IN] member name 
        //         PCCOR_SIGNATURE pvSigBlob,          // [IN] point to a blob value of CLR signature 
        //         ULONG       cbSigBlob,              // [IN] count of bytes in the signature blob    
        //         mdMethodDef *pmb) PURE;             // [OUT] matching memberdef 
        void FindMethod_();
        
        //     STDMETHOD(FindField)(   
        //         mdTypeDef   td,                     // [IN] given typedef   
        //         LPCWSTR     szName,                 // [IN] member name 
        //         PCCOR_SIGNATURE pvSigBlob,          // [IN] point to a blob value of CLR signature 
        //         ULONG       cbSigBlob,              // [IN] count of bytes in the signature blob    
        //         mdFieldDef  *pmb) PURE;             // [OUT] matching memberdef 
        void FindField_();
        
        //     STDMETHOD(FindMemberRef)(   
        //         mdTypeRef   td,                     // [IN] given typeRef   
        //         LPCWSTR     szName,                 // [IN] member name 
        //         PCCOR_SIGNATURE pvSigBlob,          // [IN] point to a blob value of CLR signature 
        //         ULONG       cbSigBlob,              // [IN] count of bytes in the signature blob    
        //         mdMemberRef *pmr) PURE;             // [OUT] matching memberref 
        void FindMemberRef_();
#endif

        //     STDMETHOD (GetMethodProps)( 
        //         mdMethodDef mb,                     // The method for which to get props.   
        //         mdTypeDef   *pClass,                // Put method's class here. 
        //         LPWSTR      szMethod,               // Put method's name here.  
        //         ULONG       cchMethod,              // Size of szMethod buffer in wide chars.   
        //         ULONG       *pchMethod,             // Put actual size here 
        //         DWORD       *pdwAttr,               // Put flags here.  
        //         PCCOR_SIGNATURE *ppvSigBlob,        // [OUT] point to the blob value of meta data   
        //         ULONG       *pcbSigBlob,            // [OUT] actual size of signature blob  
        //         ULONG       *pulCodeRVA,            // [OUT] codeRVA    
        //         DWORD       *pdwImplFlags) PURE;    // [OUT] Impl. Flags    
        void GetMethodProps([In] uint md,
                            [ComAliasName("mdTypeDef*")] [Out] out int pClass,
                            [Out, MarshalAs( UnmanagedType.LPWStr)] StringBuilder szMethod,
                            [In] int cchMethod,
                            [ComAliasName("ULONG*")] [Out] out int pchMethod,
                            [ComAliasName("DWORD*")] [Out] out uint pdwAttr,
                            [ComAliasName("PCCOR_SIGNATURE*")] [Out] out IntPtr ppvSigBlob,
                            [ComAliasName("ULONG*")] [Out] out uint pcbSigBlob,
                            [ComAliasName("ULONG*")] [Out] out uint pulCodeRVA,
                            [ComAliasName("DWORD*")] [Out] out uint pdwImplFlags
                            );
        
        //     STDMETHOD(GetMemberRefProps)(           // S_OK or error.   
        //         mdMemberRef mr,                     // [IN] given memberref 
        //         mdToken     *ptk,                   // [OUT] Put classref or classdef here. 
        //         LPWSTR      szMember,               // [OUT] buffer to fill for member's name   
        //         ULONG       cchMember,              // [IN] the count of char of szMember   
        //         ULONG       *pchMember,             // [OUT] actual count of char in member name    
        //         PCCOR_SIGNATURE *ppvSigBlob,        // [OUT] point to meta data blob value  
        //         ULONG       *pbSig) PURE;           // [OUT] actual size of signature blob  
        void GetMemberRefProps([In] uint mr,
                               [ComAliasName("mdMemberRef*")] [Out] out int ptk,
                               [Out,MarshalAs(UnmanagedType.LPWStr)] StringBuilder szMember,
                               [In] int cchMember,
                               [ComAliasName("ULONG*")] [Out] out uint pchMember,
                               [ComAliasName("PCCOR_SIGNATURE*")] [Out] out IntPtr ppvSigBlob,
                               [ComAliasName("ULONG*")] [Out] out int pbSig
                               );
        
#if !MDBG_FAKE_COM
        //     STDMETHOD(EnumProperties)(              // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdTypeDef   td,                     // [IN] TypeDef to scope the enumeration.   
        //         mdProperty  rProperties[],          // [OUT] Put Properties here.   
        //         ULONG       cMax,                   // [IN] Max properties to put.  
        //         ULONG       *pcProperties) PURE;    // [OUT] Put # put here.    
        void EnumProperties_();
        
        //     STDMETHOD(EnumEvents)(                  // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdTypeDef   td,                     // [IN] TypeDef to scope the enumeration.   
        //         mdEvent     rEvents[],              // [OUT] Put events here.   
        //         ULONG       cMax,                   // [IN] Max events to put.  
        //         ULONG       *pcEvents) PURE;        // [OUT] Put # put here.    
        void EnumEvents_();
        
        //     STDMETHOD(GetEventProps)(               // S_OK, S_FALSE, or error. 
        //         mdEvent     ev,                     // [IN] event token 
        //         mdTypeDef   *pClass,                // [OUT] typedef containing the event declarion.    
        //         LPCWSTR     szEvent,                // [OUT] Event name 
        //         ULONG       cchEvent,               // [IN] the count of wchar of szEvent   
        //         ULONG       *pchEvent,              // [OUT] actual count of wchar for event's name 
        //         DWORD       *pdwEventFlags,         // [OUT] Event flags.   
        //         mdToken     *ptkEventType,          // [OUT] EventType class    
        //         mdMethodDef *pmdAddOn,              // [OUT] AddOn method of the event  
        //         mdMethodDef *pmdRemoveOn,           // [OUT] RemoveOn method of the event   
        //         mdMethodDef *pmdFire,               // [OUT] Fire method of the event   
        //         mdMethodDef rmdOtherMethod[],       // [OUT] other method of the event  
        //         ULONG       cMax,                   // [IN] size of rmdOtherMethod  
        //         ULONG       *pcOtherMethod) PURE;   // [OUT] total number of other method of this event 
        void GetEventProps_();
        
        //     STDMETHOD(EnumMethodSemantics)(         // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdMethodDef mb,                     // [IN] MethodDef to scope the enumeration. 
        //         mdToken     rEventProp[],           // [OUT] Put Event/Property here.   
        //         ULONG       cMax,                   // [IN] Max properties to put.  
        //         ULONG       *pcEventProp) PURE;     // [OUT] Put # put here.    
        void EnumMethodSemantics_();
        
        //     STDMETHOD(GetMethodSemantics)(          // S_OK, S_FALSE, or error. 
        //         mdMethodDef mb,                     // [IN] method token    
        //         mdToken     tkEventProp,            // [IN] event/property token.   
        //         DWORD       *pdwSemanticsFlags) PURE; // [OUT] the role flags for the method/propevent pair 
        void GetMethodSemantics_();
        
        //     STDMETHOD(GetClassLayout) ( 
        //         mdTypeDef   td,                     // [IN] give typedef    
        //         DWORD       *pdwPackSize,           // [OUT] 1, 2, 4, 8, or 16  
        //         COR_FIELD_OFFSET rFieldOffset[],    // [OUT] field offset array 
        //         ULONG       cMax,                   // [IN] size of the array   
        //         ULONG       *pcFieldOffset,         // [OUT] needed array size  
        //         ULONG       *pulClassSize) PURE;        // [OUT] the size of the class  
        void GetClassLayout_();
        
        //     STDMETHOD(GetFieldMarshal) (    
        //         mdToken     tk,                     // [IN] given a field's memberdef   
        //         PCCOR_SIGNATURE *ppvNativeType,     // [OUT] native type of this field  
        //         ULONG       *pcbNativeType) PURE;   // [OUT] the count of bytes of *ppvNativeType   
        void GetFieldMarshal_();
        
        //     STDMETHOD(GetRVA)(                      // S_OK or error.   
        //         mdToken     tk,                     // Member for which to set offset   
        //         ULONG       *pulCodeRVA,            // The offset   
        //         DWORD       *pdwImplFlags) PURE;    // the implementation flags 
        void GetRVA_();
        
        //     STDMETHOD(GetPermissionSetProps) (  
        //         mdPermission pm,                    // [IN] the permission token.   
        //         DWORD       *pdwAction,             // [OUT] CorDeclSecurity.   
        //         void const  **ppvPermission,        // [OUT] permission blob.   
        //         ULONG       *pcbPermission) PURE;   // [OUT] count of bytes of pvPermission.    
        void GetPermissionSetProps_();
        
        //     STDMETHOD(GetSigFromToken)(             // S_OK or error.   
        //         mdSignature mdSig,                  // [IN] Signature token.    
        //         PCCOR_SIGNATURE *ppvSig,            // [OUT] return pointer to token.   
        //         ULONG       *pcbSig) PURE;          // [OUT] return size of signature.  
        void GetSigFromToken_();
        
        //     STDMETHOD(GetModuleRefProps)(           // S_OK or error.   
        //         mdModuleRef mur,                    // [IN] moduleref token.    
        //         LPWSTR      szName,                 // [OUT] buffer to fill with the moduleref name.    
        //         ULONG       cchName,                // [IN] size of szName in wide characters.  
        //         ULONG       *pchName) PURE;         // [OUT] actual count of characters in the name.    
        void GetModuleRefProps_();
        
        //     STDMETHOD(EnumModuleRefs)(              // S_OK or error.   
        //         HCORENUM    *phEnum,                // [IN|OUT] pointer to the enum.    
        //         mdModuleRef rModuleRefs[],          // [OUT] put modulerefs here.   
        //         ULONG       cmax,                   // [IN] max memberrefs to put.  
        //         ULONG       *pcModuleRefs) PURE;    // [OUT] put # put here.    
        void EnumModuleRefs_();
        
        //     STDMETHOD(GetTypeSpecFromToken)(        // S_OK or error.   
        //         mdTypeSpec typespec,                // [IN] TypeSpec token.    
        //         PCCOR_SIGNATURE *ppvSig,            // [OUT] return pointer to TypeSpec signature  
        //         ULONG       *pcbSig) PURE;          // [OUT] return size of signature.  
        void GetTypeSpecFromToken_();
         
        //     STDMETHOD(GetNameFromToken)(            // Not Recommended! May be removed!
        //         mdToken     tk,                     // [IN] Token to get name from.  Must have a name.
        //         MDUTF8CSTR  *pszUtf8NamePtr) PURE;  // [OUT] Return pointer to UTF8 name in heap.
        void GetNameFromToken_();
        

        //     STDMETHOD(EnumUnresolvedMethods)(       // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdToken     rMethods[],             // [OUT] Put MemberDefs here.   
        //         ULONG       cMax,                   // [IN] Max MemberDefs to put.  
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.
        void EnumUnresolvedMethods_();
#endif

        //     STDMETHOD(GetUserString)(               // S_OK or error.
        //         mdString    stk,                    // [IN] String token.
        //         LPWSTR      szString,               // [OUT] Copy of string.
        //         ULONG       cchString,              // [IN] Max chars of room in szString.
        //         ULONG       *pchString) PURE;       // [OUT] How many chars in actual string.
        void GetUserString([In] int stk,
                           [Out,MarshalAs(UnmanagedType.LPWStr)] StringBuilder szString,
                           [In] int cchString,
                           [ComAliasName("ULONG*")] out  int pchString
                           );

#if !MDBG_FAKE_COM
        //     STDMETHOD(GetPinvokeMap)(               // S_OK or error.
        //         mdToken     tk,                     // [IN] FieldDef or MethodDef.
        //         DWORD       *pdwMappingFlags,       // [OUT] Flags used for mapping.
        //         LPWSTR      szImportName,           // [OUT] Import name.
        //         ULONG       cchImportName,          // [IN] Size of the name buffer.
        //         ULONG       *pchImportName,         // [OUT] Actual number of characters stored.
        //         mdModuleRef *pmrImportDLL) PURE;    // [OUT] ModuleRef token for the target DLL.
        void GetPinvokeMap_();

        //     STDMETHOD(EnumSignatures)(              // S_OK or error.
        //         HCORENUM    *phEnum,                // [IN|OUT] pointer to the enum.    
        //         mdSignature rSignatures[],          // [OUT] put signatures here.   
        //         ULONG       cmax,                   // [IN] max signatures to put.  
        //         ULONG       *pcSignatures) PURE;    // [OUT] put # put here.
        void EnumSignatures_();

        //     STDMETHOD(EnumTypeSpecs)(               // S_OK or error.
        //         HCORENUM    *phEnum,                // [IN|OUT] pointer to the enum.    
        //         mdTypeSpec  rTypeSpecs[],           // [OUT] put TypeSpecs here.   
        //         ULONG       cmax,                   // [IN] max TypeSpecs to put.  
        //         ULONG       *pcTypeSpecs) PURE;     // [OUT] put # put here.
        void EnumTypeSpecs_();

        //     STDMETHOD(EnumUserStrings)(             // S_OK or error.
        //         HCORENUM    *phEnum,                // [IN/OUT] pointer to the enum.
        //         mdString    rStrings[],             // [OUT] put Strings here.
        //         ULONG       cmax,                   // [IN] max Strings to put.
        //         ULONG       *pcStrings) PURE;       // [OUT] put # put here.
        void EnumUserStrings_();

        //     STDMETHOD(GetParamForMethodIndex)(      // S_OK or error.
        //         mdMethodDef md,                     // [IN] Method token.
        //         ULONG       ulParamSeq,             // [IN] Parameter sequence.
        //         mdParamDef  *ppd) PURE;             // [IN] Put Param token here.
        void GetParamForMethodIndex_();
#endif

        //     STDMETHOD(EnumCustomAttributes)(        // S_OK or error.
        //         HCORENUM    *phEnum,                // [IN, OUT] COR enumerator.
        //         mdToken     tk,                     // [IN] Token to scope the enumeration, 0 for all.
        //         mdToken     tkType,                 // [IN] Type of interest, 0 for all.
        //         mdCustomAttribute rCustomAttributes[], // [OUT] Put custom attribute tokens here.
        //         ULONG       cMax,                   // [IN] Size of rCustomAttributes.
        //         ULONG       *pcCustomAttributes) PURE;  // [OUT, OPTIONAL] Put count of token values here.
        void EnumCustomAttributes(ref IntPtr phEnum,
                         int tk,
                         int tkType,
                         [ComAliasName("mdCustomAttribute*")]out int mdCustomAttribute,
                         uint cMax /*must be 1*/,
                         [ComAliasName("ULONG*")]out uint pcTokens
                         );

#if !MDBG_FAKE_COM
        //     STDMETHOD(GetCustomAttributeProps)(     // S_OK or error.
        //         mdCustomAttribute cv,               // [IN] CustomAttribute token.
        //         mdToken     *ptkObj,                // [OUT, OPTIONAL] Put object token here.
        //         mdToken     *ptkType,               // [OUT, OPTIONAL] Put AttrType token here.
        //         void const  **ppBlob,               // [OUT, OPTIONAL] Put pointer to data here.
        //         ULONG       *pcbSize) PURE;         // [OUT, OPTIONAL] Put size of date here.
        void GetCustomAttributeProps_();

        //     STDMETHOD(FindTypeRef)(   
        //         mdToken     tkResolutionScope,      // [IN] ModuleRef, AssemblyRef or TypeRef.
        //         LPCWSTR     szName,                 // [IN] TypeRef Name.
        //         mdTypeRef   *ptr) PURE;             // [OUT] matching TypeRef.
        void FindTypeRef_();

        //     STDMETHOD(GetMemberProps)(  
        //         mdToken     mb,                     // The member for which to get props.   
        //         mdTypeDef   *pClass,                // Put member's class here. 
        //         LPWSTR      szMember,               // Put member's name here.  
        //         ULONG       cchMember,              // Size of szMember buffer in wide chars.   
        //         ULONG       *pchMember,             // Put actual size here 
        //         DWORD       *pdwAttr,               // Put flags here.  
        //         PCCOR_SIGNATURE *ppvSigBlob,        // [OUT] point to the blob value of meta data   
        //         ULONG       *pcbSigBlob,            // [OUT] actual size of signature blob  
        //         ULONG       *pulCodeRVA,            // [OUT] codeRVA    
        //         DWORD       *pdwImplFlags,          // [OUT] Impl. Flags    
        //         DWORD       *pdwCPlusTypeFlag,      // [OUT] flag for value type. selected ELEMENT_TYPE_*   
        //         void const  **ppValue,              // [OUT] constant value 
        //         ULONG       *pcchValue) PURE;       // [OUT] size of constant string in chars, 0 for non-strings.
        void GetMemberProps_();
#endif

        //     STDMETHOD(GetFieldProps)(  
        //         mdFieldDef  mb,                     // The field for which to get props.    
        //         mdTypeDef   *pClass,                // Put field's class here.  
        //         LPWSTR      szField,                // Put field's name here.   
        //         ULONG       cchField,               // Size of szField buffer in wide chars.    
        //         ULONG       *pchField,              // Put actual size here 
        //         DWORD       *pdwAttr,               // Put flags here.  
        //         PCCOR_SIGNATURE *ppvSigBlob,        // [OUT] point to the blob value of meta data   
        //         ULONG       *pcbSigBlob,            // [OUT] actual size of signature blob  
        //         DWORD       *pdwCPlusTypeFlag,      // [OUT] flag for value type. selected ELEMENT_TYPE_*   
        //         void const  **ppValue,              // [OUT] constant value 
        //         ULONG       *pcchValue) PURE;       // [OUT] size of constant string in chars, 0 for non-strings.
        void GetFieldProps(int mb,
                           [ComAliasName("mdTypeDef*")] out int mdTypeDef,
                           [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder szField,
                           int cchField,
                           [ComAliasName("ULONG*")] out int pchField,
                           [ComAliasName("DWORD*")] out int pdwAttr,
                           [ComAliasName("PCCOR_SIGNATURE*")] out IntPtr ppvSigBlob,
                           [ComAliasName("ULONG*")] out int pcbSigBlob,
                           [ComAliasName("DWORD*")] out int pdwCPlusTypeFlab,
                           [ComAliasName("UVCP_CONSTANT*")] out IntPtr ppValue,
                           [ComAliasName("ULONG*")] out int pcchValue
                           );

#if !MDBG_FAKE_COM
        //     STDMETHOD(GetPropertyProps)(            // S_OK, S_FALSE, or error. 
        //         mdProperty  prop,                   // [IN] property token  
        //         mdTypeDef   *pClass,                // [OUT] typedef containing the property declarion. 
        //         LPCWSTR     szProperty,             // [OUT] Property name  
        //         ULONG       cchProperty,            // [IN] the count of wchar of szProperty    
        //         ULONG       *pchProperty,           // [OUT] actual count of wchar for property name    
        //         DWORD       *pdwPropFlags,          // [OUT] property flags.    
        //         PCCOR_SIGNATURE *ppvSig,            // [OUT] property type. pointing to meta data internal blob 
        //         ULONG       *pbSig,                 // [OUT] count of bytes in *ppvSig  
        //         DWORD       *pdwCPlusTypeFlag,      // [OUT] flag for value type. selected ELEMENT_TYPE_*   
        //         void const  **ppDefaultValue,       // [OUT] constant value 
        //         ULONG       *pcchDefaultValue,      // [OUT] size of constant string in chars, 0 for non-strings.
        //         mdMethodDef *pmdSetter,             // [OUT] setter method of the property  
        //         mdMethodDef *pmdGetter,             // [OUT] getter method of the property  
        //         mdMethodDef rmdOtherMethod[],       // [OUT] other method of the property   
        //         ULONG       cMax,                   // [IN] size of rmdOtherMethod  
        //         ULONG       *pcOtherMethod) PURE;   // [OUT] total number of other method of this property
        void GetPropertyProps_();
#endif

        //     STDMETHOD(GetParamProps)(               // S_OK or error.
        //         mdParamDef  tk,                     // [IN]The Parameter.
        //         mdMethodDef *pmd,                   // [OUT] Parent Method token.
        //         ULONG       *pulSequence,           // [OUT] Parameter sequence.
        //         LPWSTR      szName,                 // [OUT] Put name here.
        //         ULONG       cchName,                // [OUT] Size of name buffer.
        //         ULONG       *pchName,               // [OUT] Put actual size of name here.
        //         DWORD       *pdwAttr,               // [OUT] Put flags here.
        //         DWORD       *pdwCPlusTypeFlag,      // [OUT] Flag for value type. selected ELEMENT_TYPE_*.
        //         void const  **ppValue,              // [OUT] Constant value.
        //         ULONG       *pcchValue) PURE;       // [OUT] size of constant string in chars, 0 for non-strings.
        void GetParamProps(int tk,
                           [ComAliasName("mdMethodDef*")] out int pmd,
                           [ComAliasName("ULONG*")] out uint pulSequence,
                           [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName,
                           uint cchName,
                           [ComAliasName("ULONG*")] out uint pchName,
                           [ComAliasName("DWORD*")] out uint pdwAttr,
                           [ComAliasName("DWORD*")] out uint pdwCPlusTypeFlag,
                           [ComAliasName("UVCP_CONSTANT*")] out IntPtr ppValue,
                           [ComAliasName("ULONG*")] out uint pcchValue
                           );

        //     STDMETHOD(GetCustomAttributeByName)(    // S_OK or error.
        //         mdToken     tkObj,                  // [IN] Object with Custom Attribute.
        //         LPCWSTR     szName,                 // [IN] Name of desired Custom Attribute.
        //         const void  **ppData,               // [OUT] Put pointer to data here.
        //         ULONG       *pcbData) PURE;         // [OUT] Put size of data here.
        [PreserveSig]
        int GetCustomAttributeByName(
                            int tkObj,
                            [MarshalAs(UnmanagedType.LPWStr)]string szName,
                            out IntPtr ppData,
                            out uint pcbData);

        //     STDMETHOD_(BOOL, IsValidToken)(         // True or False.
        //         mdToken     tk) PURE;               // [IN] Given token.
        [PreserveSig] bool IsValidToken([In, MarshalAs(UnmanagedType.U4)] uint tk);

        //     STDMETHOD(GetNestedClassProps)(         // S_OK or error.
        //         mdTypeDef   tdNestedClass,          // [IN] NestedClass token.
        //         mdTypeDef   *ptdEnclosingClass) PURE; // [OUT] EnclosingClass token.
        void GetNestedClassProps(int tdNestedClass, [ComAliasName("mdTypeDef*")] out int tdEnclosingClass);

#if !MDBG_FAKE_COM
        //     STDMETHOD(GetNativeCallConvFromSig)(    // S_OK or error.
        //         void const  *pvSig,                 // [IN] Pointer to signature.
        //         ULONG       cbSig,                  // [IN] Count of signature bytes.
        //         ULONG       *pCallConv) PURE;       // [OUT] Put calling conv here (see CorPinvokemap).
        void GetNativeCallConvFromSig_();

        //     STDMETHOD(IsGlobal)(                    // S_OK or error.
        //         mdToken     pd,                     // [IN] Type, Field, or Method token.
        //         int         *pbGlobal) PURE;        // [OUT] Put 1 if global, 0 otherwise.
        void IsGlobal_();
#endif
        
    }      // IMetadataImport



    // IMetaDataImport2
    [Guid("FCE5EFA0-8BBA-4f8e-A036-8F2022B08466"),
        InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
    ]
    public interface IMetadataImport2 : IMetadataImport
    {    
        // <strip>@todo - check if there will be be better way how to declare IMetadataImport2 interface.
        //       - Would be very nice if we could avoid this (tried deriving from IM, doesn't work).</strip>
        // Need imports from IMetaDataImport to adjust IM2 vtable slots.
    
        //STDMETHOD_(void, CloseEnum)(HCORENUM hEnum) PURE;
        [PreserveSig] new void CloseEnum(IntPtr hEnum);
        
        //STDMETHOD(CountEnum)(HCORENUM hEnum, ULONG *pulCount) PURE;
        new void CountEnum(IntPtr hEnum, [ComAliasName("ULONG*")] out int pulCount);
        
        //STDMETHOD(ResetEnum)(HCORENUM hEnum, ULONG ulPos) PURE;
        new void ResetEnum(IntPtr hEnum, int ulPos);
        
        //STDMETHOD(EnumTypeDefs)(HCORENUM *phEnum, mdTypeDef rTypeDefs[],ULONG cMax, ULONG *pcTypeDefs) PURE;
        //void EnumTypeDefs(out IntPtr phEnum,int[] rTypeDefs,uint cMax, out uint pcTypeDefs);  
        new void EnumTypeDefs(
                            ref IntPtr phEnum, 
                            [ComAliasName("mdTypeDef*")] out int rTypeDefs,
                            uint cMax /*must be 1*/, 
                            [ComAliasName("ULONG*")] out uint pcTypeDefs); 
        
#if !MDBG_FAKE_COM
        //STDMETHOD(EnumInterfaceImpls)(HCORENUM *phEnum, mdTypeDef td, mdInterfaceImpl rImpls[], ULONG cMax, ULONG* pcImpls) PURE;
        new void EnumInterfaceImpls_(IntPtr phEnum, int td);

        //STDMETHOD(EnumTypeRefs)(HCORENUM *phEnum, mdTypeRef rTypeRefs[], ULONG cMax, ULONG* pcTypeRefs) PURE;
        new void EnumTypeRefs_();
#endif

        //     STDMETHOD(FindTypeDefByName)(           // S_OK or error.
        //         LPCWSTR     szTypeDef,              // [IN] Name of the Type.
        //         mdToken     tkEnclosingClass,       // [IN] TypeDef/TypeRef for Enclosing class.
        //         mdTypeDef   *ptd) PURE;             // [OUT] Put the TypeDef token here.
        new void FindTypeDefByName(
                               [In, MarshalAs(UnmanagedType.LPWStr)] string szTypeDef,
                               [In] int tkEnclosingClass,
                               [ComAliasName("mdTypeDef*")] [Out] out int token
                               );
        
        //     STDMETHOD(GetScopeProps)(               // S_OK or error.
        //         LPWSTR      szName,                 // [OUT] Put the name here.
        //         ULONG       cchName,                // [IN] Size of name buffer in wide chars.
        //         ULONG       *pchName,               // [OUT] Put size of name (wide chars) here.
        //         GUID        *pmvid) PURE;           // [OUT, OPTIONAL] Put MVID here.
		new void GetScopeProps(
            [Out,MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName,
            [In] int cchName,
            [ComAliasName("ULONG*")] out int pchName,
            out Guid mvid    
		);

#if !MDBG_FAKE_COM
        //     STDMETHOD(GetModuleFromScope)(          // S_OK.
        //         mdModule    *pmd) PURE;             // [OUT] Put mdModule token here.
        new void GetModuleFromScope_();
#endif

        //     STDMETHOD(GetTypeDefProps)(             // S_OK or error.
        //         mdTypeDef   td,                     // [IN] TypeDef token for inquiry.
        //         LPWSTR      szTypeDef,              // [OUT] Put name here.
        //         ULONG       cchTypeDef,             // [IN] size of name buffer in wide chars.
        //         ULONG       *pchTypeDef,            // [OUT] put size of name (wide chars) here.
        //         DWORD       *pdwTypeDefFlags,       // [OUT] Put flags here.
        //         mdToken     *ptkExtends) PURE;      // [OUT] Put base class TypeDef/TypeRef here.
        new void GetTypeDefProps([In] int td,
                             [Out, MarshalAs( UnmanagedType.LPWStr)] StringBuilder szTypeDef,
                             [In] int cchTypeDef,
                             [ComAliasName("ULONG*")] [Out] out int pchTypeDef,
                             [Out, MarshalAs(UnmanagedType.U4)] out System.Reflection.TypeAttributes pdwTypeDefFlags,
                             [ComAliasName("mdToken*")] [Out] out int ptkExtends
                             );

#if !MDBG_FAKE_COM
        //     STDMETHOD(GetInterfaceImplProps)(       // S_OK or error.
        //         mdInterfaceImpl iiImpl,             // [IN] InterfaceImpl token.
        //         mdTypeDef   *pClass,                // [OUT] Put implementing class token here.
        //         mdToken     *ptkIface) PURE;        // [OUT] Put implemented interface token here.
        new void GetInterfaceImplProps_();
#endif

        //     STDMETHOD(GetTypeRefProps)(             // S_OK or error.
        //         mdTypeRef   tr,                     // [IN] TypeRef token.
        //         mdToken     *ptkResolutionScope,    // [OUT] Resolution scope, ModuleRef or AssemblyRef.
        //         LPWSTR      szName,                 // [OUT] Name of the TypeRef.
        //         ULONG       cchName,                // [IN] Size of buffer.
        //         ULONG       *pchName) PURE;         // [OUT] Size of Name.
        new void GetTypeRefProps(
                             int tr,
                             [ComAliasName("mdToken*")] [Out] out int ptkResolutionScope,
                             [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName,
                             [In] int cchName,
                             [ComAliasName("ULONG*")] out int pchName
                             );

#if !MDBG_FAKE_COM
        //     STDMETHOD(ResolveTypeRef)(mdTypeRef tr, REFIID riid, IUnknown **ppIScope, mdTypeDef *ptd) PURE;
        new void ResolveTypeRef_();

        //     STDMETHOD(EnumMembers)(                 // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdTypeDef   cl,                     // [IN] TypeDef to scope the enumeration.   
        //         mdToken     rMembers[],             // [OUT] Put MemberDefs here.   
        //         ULONG       cMax,                   // [IN] Max MemberDefs to put.  
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        new void EnumMembers_();
        
        //     STDMETHOD(EnumMembersWithName)(         // S_OK, S_FALSE, or error.             
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.                
        //         mdTypeDef   cl,                     // [IN] TypeDef to scope the enumeration.   
        //         LPCWSTR     szName,                 // [IN] Limit results to those with this name.              
        //         mdToken     rMembers[],             // [OUT] Put MemberDefs here.                   
        //         ULONG       cMax,                   // [IN] Max MemberDefs to put.              
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        new void EnumMembersWithName_();
#endif
        
        //     STDMETHOD(EnumMethods)(                 // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdTypeDef   cl,                     // [IN] TypeDef to scope the enumeration.   
        //         mdMethodDef rMethods[],             // [OUT] Put MethodDefs here.   
        //         ULONG       cMax,                   // [IN] Max MethodDefs to put.  
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        new void EnumMethods(ref IntPtr phEnum,
                         int cl,
                         [ComAliasName("mdMethodDef*")] out int mdMethodDef,
                         int cMax, /*must be 1*/
                         [ComAliasName("ULONG*")] out int pcTokens
                         );

#if !MDBG_FAKE_COM        
        //     STDMETHOD(EnumMethodsWithName)(         // S_OK, S_FALSE, or error.             
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.                
        //         mdTypeDef   cl,                     // [IN] TypeDef to scope the enumeration.   
        //         LPCWSTR     szName,                 // [IN] Limit results to those with this name.              
        //         mdMethodDef rMethods[],             // [OU] Put MethodDefs here.    
        //         ULONG       cMax,                   // [IN] Max MethodDefs to put.              
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        new void EnumMethodsWithName_();
#endif
        
        //     STDMETHOD(EnumFields)(                 // S_OK, S_FALSE, or error.  
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdTypeDef   cl,                     // [IN] TypeDef to scope the enumeration.   
        //         mdFieldDef  rFields[],              // [OUT] Put FieldDefs here.    
        //         ULONG       cMax,                   // [IN] Max FieldDefs to put.   
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        /*[PreserveSig]*/
        new void EnumFields(ref IntPtr phEnum,
                        int cl,
                        [ComAliasName("mdFieldDef*")] out int mdFieldDef,
                        int cMax /*must be 1*/, 
                        [ComAliasName("ULONG*")] out uint pcTokens); 

#if !MDBG_FAKE_COM        
        //     STDMETHOD(EnumFieldsWithName)(         // S_OK, S_FALSE, or error.              
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.                
        //         mdTypeDef   cl,                     // [IN] TypeDef to scope the enumeration.   
        //         LPCWSTR     szName,                 // [IN] Limit results to those with this name.              
        //         mdFieldDef  rFields[],              // [OUT] Put MemberDefs here.                   
        //         ULONG       cMax,                   // [IN] Max MemberDefs to put.              
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        new void EnumFieldsWithName_();
#endif

        //     STDMETHOD(EnumParams)(                  // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdMethodDef mb,                     // [IN] MethodDef to scope the enumeration. 
        //         mdParamDef  rParams[],              // [OUT] Put ParamDefs here.    
        //         ULONG       cMax,                   // [IN] Max ParamDefs to put.   
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.
        new void EnumParams(ref IntPtr phEnum,
                        int mdMethodDef,
                        [ComAliasName("mdParamDef*")] out int mdParamDef,
                        int cMax /*must be 1*/,
                        [ComAliasName("ULONG*")] out uint pcTokens);

#if !MDBG_FAKE_COM
        //     STDMETHOD(EnumMemberRefs)(              // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdToken     tkParent,               // [IN] Parent token to scope the enumeration.  
        //         mdMemberRef rMemberRefs[],          // [OUT] Put MemberRefs here.   
        //         ULONG       cMax,                   // [IN] Max MemberRefs to put.  
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        new void EnumMemberRefs_();

        //     STDMETHOD(EnumMethodImpls)(             // S_OK, S_FALSE, or error  
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdTypeDef   td,                     // [IN] TypeDef to scope the enumeration.   
        //         mdToken     rMethodBody[],          // [OUT] Put Method Body tokens here.   
        //         mdToken     rMethodDecl[],          // [OUT] Put Method Declaration tokens here.
        //         ULONG       cMax,                   // [IN] Max tokens to put.  
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        new void EnumMethodImpls_();
        
        //     STDMETHOD(EnumPermissionSets)(          // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdToken     tk,                     // [IN] if !NIL, token to scope the enumeration.    
        //         DWORD       dwActions,              // [IN] if !0, return only these actions.   
        //         mdPermission rPermission[],         // [OUT] Put Permissions here.  
        //         ULONG       cMax,                   // [IN] Max Permissions to put. 
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.    
        new void EnumPermissionSets_();
        
        //     STDMETHOD(FindMember)(  
        //         mdTypeDef   td,                     // [IN] given typedef   
        //         LPCWSTR     szName,                 // [IN] member name 
        //         PCCOR_SIGNATURE pvSigBlob,          // [IN] point to a blob value of CLR signature 
        //         ULONG       cbSigBlob,              // [IN] count of bytes in the signature blob    
        //         mdToken     *pmb) PURE;             // [OUT] matching memberdef 
        new void FindMember_();
        
        //     STDMETHOD(FindMethod)(  
        //         mdTypeDef   td,                     // [IN] given typedef   
        //         LPCWSTR     szName,                 // [IN] member name 
        //         PCCOR_SIGNATURE pvSigBlob,          // [IN] point to a blob value of CLR signature 
        //         ULONG       cbSigBlob,              // [IN] count of bytes in the signature blob    
        //         mdMethodDef *pmb) PURE;             // [OUT] matching memberdef 
        new void FindMethod_();
        
        //     STDMETHOD(FindField)(   
        //         mdTypeDef   td,                     // [IN] given typedef   
        //         LPCWSTR     szName,                 // [IN] member name 
        //         PCCOR_SIGNATURE pvSigBlob,          // [IN] point to a blob value of CLR signature 
        //         ULONG       cbSigBlob,              // [IN] count of bytes in the signature blob    
        //         mdFieldDef  *pmb) PURE;             // [OUT] matching memberdef 
        new void FindField_();
        
        //     STDMETHOD(FindMemberRef)(   
        //         mdTypeRef   td,                     // [IN] given typeRef   
        //         LPCWSTR     szName,                 // [IN] member name 
        //         PCCOR_SIGNATURE pvSigBlob,          // [IN] point to a blob value of CLR signature 
        //         ULONG       cbSigBlob,              // [IN] count of bytes in the signature blob    
        //         mdMemberRef *pmr) PURE;             // [OUT] matching memberref 
        new void FindMemberRef_();
#endif

        //     STDMETHOD (GetMethodProps)( 
        //         mdMethodDef mb,                     // The method for which to get props.   
        //         mdTypeDef   *pClass,                // Put method's class here. 
        //         LPWSTR      szMethod,               // Put method's name here.  
        //         ULONG       cchMethod,              // Size of szMethod buffer in wide chars.   
        //         ULONG       *pchMethod,             // Put actual size here 
        //         DWORD       *pdwAttr,               // Put flags here.  
        //         PCCOR_SIGNATURE *ppvSigBlob,        // [OUT] point to the blob value of meta data   
        //         ULONG       *pcbSigBlob,            // [OUT] actual size of signature blob  
        //         ULONG       *pulCodeRVA,            // [OUT] codeRVA    
        //         DWORD       *pdwImplFlags) PURE;    // [OUT] Impl. Flags    
        new void GetMethodProps([In] uint md,
                            [ComAliasName("mdTypeDef*")] [Out] out int pClass,
                            [Out, MarshalAs( UnmanagedType.LPWStr)] StringBuilder szMethod,
                            [In] int cchMethod,
                            [ComAliasName("ULONG*")] [Out] out int pchMethod,
                            [ComAliasName("DWORD*")] [Out] out uint pdwAttr,
                            [ComAliasName("PCCOR_SIGNATURE*")] [Out] out IntPtr ppvSigBlob,
                            [ComAliasName("ULONG*")] [Out] out uint pcbSigBlob,
                            [ComAliasName("ULONG*")] [Out] out uint pulCodeRVA,
                            [ComAliasName("DWORD*")] [Out] out uint pdwImplFlags
                            );
        
        //     STDMETHOD(GetMemberRefProps)(           // S_OK or error.   
        //         mdMemberRef mr,                     // [IN] given memberref 
        //         mdToken     *ptk,                   // [OUT] Put classref or classdef here. 
        //         LPWSTR      szMember,               // [OUT] buffer to fill for member's name   
        //         ULONG       cchMember,              // [IN] the count of char of szMember   
        //         ULONG       *pchMember,             // [OUT] actual count of char in member name    
        //         PCCOR_SIGNATURE *ppvSigBlob,        // [OUT] point to meta data blob value  
        //         ULONG       *pbSig) PURE;           // [OUT] actual size of signature blob  
        new void GetMemberRefProps([In] uint mr,
                               [ComAliasName("mdMemberRef*")] [Out] out int ptk,
                               [Out,MarshalAs(UnmanagedType.LPWStr)] StringBuilder szMember,
                               [In] int cchMember,
                               [ComAliasName("ULONG*")] [Out] out uint pchMember,
                               [ComAliasName("PCCOR_SIGNATURE*")] [Out] out IntPtr ppvSigBlob,
                               [ComAliasName("ULONG*")] [Out] out int pbSig
                               );
        
#if !MDBG_FAKE_COM
        //     STDMETHOD(EnumProperties)(              // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdTypeDef   td,                     // [IN] TypeDef to scope the enumeration.   
        //         mdProperty  rProperties[],          // [OUT] Put Properties here.   
        //         ULONG       cMax,                   // [IN] Max properties to put.  
        //         ULONG       *pcProperties) PURE;    // [OUT] Put # put here.    
        new void EnumProperties_();
        
        //     STDMETHOD(EnumEvents)(                  // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdTypeDef   td,                     // [IN] TypeDef to scope the enumeration.   
        //         mdEvent     rEvents[],              // [OUT] Put events here.   
        //         ULONG       cMax,                   // [IN] Max events to put.  
        //         ULONG       *pcEvents) PURE;        // [OUT] Put # put here.    
        new void EnumEvents_();
        
        //     STDMETHOD(GetEventProps)(               // S_OK, S_FALSE, or error. 
        //         mdEvent     ev,                     // [IN] event token 
        //         mdTypeDef   *pClass,                // [OUT] typedef containing the event declarion.    
        //         LPCWSTR     szEvent,                // [OUT] Event name 
        //         ULONG       cchEvent,               // [IN] the count of wchar of szEvent   
        //         ULONG       *pchEvent,              // [OUT] actual count of wchar for event's name 
        //         DWORD       *pdwEventFlags,         // [OUT] Event flags.   
        //         mdToken     *ptkEventType,          // [OUT] EventType class    
        //         mdMethodDef *pmdAddOn,              // [OUT] AddOn method of the event  
        //         mdMethodDef *pmdRemoveOn,           // [OUT] RemoveOn method of the event   
        //         mdMethodDef *pmdFire,               // [OUT] Fire method of the event   
        //         mdMethodDef rmdOtherMethod[],       // [OUT] other method of the event  
        //         ULONG       cMax,                   // [IN] size of rmdOtherMethod  
        //         ULONG       *pcOtherMethod) PURE;   // [OUT] total number of other method of this event 
        new void GetEventProps_();
        
        //     STDMETHOD(EnumMethodSemantics)(         // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdMethodDef mb,                     // [IN] MethodDef to scope the enumeration. 
        //         mdToken     rEventProp[],           // [OUT] Put Event/Property here.   
        //         ULONG       cMax,                   // [IN] Max properties to put.  
        //         ULONG       *pcEventProp) PURE;     // [OUT] Put # put here.    
        new void EnumMethodSemantics_();
        
        //     STDMETHOD(GetMethodSemantics)(          // S_OK, S_FALSE, or error. 
        //         mdMethodDef mb,                     // [IN] method token    
        //         mdToken     tkEventProp,            // [IN] event/property token.   
        //         DWORD       *pdwSemanticsFlags) PURE; // [OUT] the role flags for the method/propevent pair 
        new void GetMethodSemantics_();
        
        //     STDMETHOD(GetClassLayout) ( 
        //         mdTypeDef   td,                     // [IN] give typedef    
        //         DWORD       *pdwPackSize,           // [OUT] 1, 2, 4, 8, or 16  
        //         COR_FIELD_OFFSET rFieldOffset[],    // [OUT] field offset array 
        //         ULONG       cMax,                   // [IN] size of the array   
        //         ULONG       *pcFieldOffset,         // [OUT] needed array size  
        //         ULONG       *pulClassSize) PURE;        // [OUT] the size of the class  
        new void GetClassLayout_();
        
        //     STDMETHOD(GetFieldMarshal) (    
        //         mdToken     tk,                     // [IN] given a field's memberdef   
        //         PCCOR_SIGNATURE *ppvNativeType,     // [OUT] native type of this field  
        //         ULONG       *pcbNativeType) PURE;   // [OUT] the count of bytes of *ppvNativeType   
        new void GetFieldMarshal_();
        
        //     STDMETHOD(GetRVA)(                      // S_OK or error.   
        //         mdToken     tk,                     // Member for which to set offset   
        //         ULONG       *pulCodeRVA,            // The offset   
        //         DWORD       *pdwImplFlags) PURE;    // the implementation flags 
        new void GetRVA_();
        
        //     STDMETHOD(GetPermissionSetProps) (  
        //         mdPermission pm,                    // [IN] the permission token.   
        //         DWORD       *pdwAction,             // [OUT] CorDeclSecurity.   
        //         void const  **ppvPermission,        // [OUT] permission blob.   
        //         ULONG       *pcbPermission) PURE;   // [OUT] count of bytes of pvPermission.    
        new void GetPermissionSetProps_();
        
        //     STDMETHOD(GetSigFromToken)(             // S_OK or error.   
        //         mdSignature mdSig,                  // [IN] Signature token.    
        //         PCCOR_SIGNATURE *ppvSig,            // [OUT] return pointer to token.   
        //         ULONG       *pcbSig) PURE;          // [OUT] return size of signature.  
        new void GetSigFromToken_();
        
        //     STDMETHOD(GetModuleRefProps)(           // S_OK or error.   
        //         mdModuleRef mur,                    // [IN] moduleref token.    
        //         LPWSTR      szName,                 // [OUT] buffer to fill with the moduleref name.    
        //         ULONG       cchName,                // [IN] size of szName in wide characters.  
        //         ULONG       *pchName) PURE;         // [OUT] actual count of characters in the name.    
        new void GetModuleRefProps_();
        
        //     STDMETHOD(EnumModuleRefs)(              // S_OK or error.   
        //         HCORENUM    *phEnum,                // [IN|OUT] pointer to the enum.    
        //         mdModuleRef rModuleRefs[],          // [OUT] put modulerefs here.   
        //         ULONG       cmax,                   // [IN] max memberrefs to put.  
        //         ULONG       *pcModuleRefs) PURE;    // [OUT] put # put here.    
        new void EnumModuleRefs_();
        
        //     STDMETHOD(GetTypeSpecFromToken)(        // S_OK or error.   
        //         mdTypeSpec typespec,                // [IN] TypeSpec token.    
        //         PCCOR_SIGNATURE *ppvSig,            // [OUT] return pointer to TypeSpec signature  
        //         ULONG       *pcbSig) PURE;          // [OUT] return size of signature.  
        new void GetTypeSpecFromToken_();
         
        //     STDMETHOD(GetNameFromToken)(            // Not Recommended! May be removed!
        //         mdToken     tk,                     // [IN] Token to get name from.  Must have a name.
        //         MDUTF8CSTR  *pszUtf8NamePtr) PURE;  // [OUT] Return pointer to UTF8 name in heap.
        new void GetNameFromToken_();
        

        //     STDMETHOD(EnumUnresolvedMethods)(       // S_OK, S_FALSE, or error. 
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdToken     rMethods[],             // [OUT] Put MemberDefs here.   
        //         ULONG       cMax,                   // [IN] Max MemberDefs to put.  
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.
        new void EnumUnresolvedMethods_();
#endif

        //     STDMETHOD(GetUserString)(               // S_OK or error.
        //         mdString    stk,                    // [IN] String token.
        //         LPWSTR      szString,               // [OUT] Copy of string.
        //         ULONG       cchString,              // [IN] Max chars of room in szString.
        //         ULONG       *pchString) PURE;       // [OUT] How many chars in actual string.
        new void GetUserString([In] int stk,
                           [Out,MarshalAs(UnmanagedType.LPWStr)] StringBuilder szString,
                           [In] int cchString,
                           [ComAliasName("ULONG*")] out  int pchString
                           );

#if !MDBG_FAKE_COM
        //     STDMETHOD(GetPinvokeMap)(               // S_OK or error.
        //         mdToken     tk,                     // [IN] FieldDef or MethodDef.
        //         DWORD       *pdwMappingFlags,       // [OUT] Flags used for mapping.
        //         LPWSTR      szImportName,           // [OUT] Import name.
        //         ULONG       cchImportName,          // [IN] Size of the name buffer.
        //         ULONG       *pchImportName,         // [OUT] Actual number of characters stored.
        //         mdModuleRef *pmrImportDLL) PURE;    // [OUT] ModuleRef token for the target DLL.
        new void GetPinvokeMap_();

        //     STDMETHOD(EnumSignatures)(              // S_OK or error.
        //         HCORENUM    *phEnum,                // [IN|OUT] pointer to the enum.    
        //         mdSignature rSignatures[],          // [OUT] put signatures here.   
        //         ULONG       cmax,                   // [IN] max signatures to put.  
        //         ULONG       *pcSignatures) PURE;    // [OUT] put # put here.
        new void EnumSignatures_();

        //     STDMETHOD(EnumTypeSpecs)(               // S_OK or error.
        //         HCORENUM    *phEnum,                // [IN|OUT] pointer to the enum.    
        //         mdTypeSpec  rTypeSpecs[],           // [OUT] put TypeSpecs here.   
        //         ULONG       cmax,                   // [IN] max TypeSpecs to put.  
        //         ULONG       *pcTypeSpecs) PURE;     // [OUT] put # put here.
        new void EnumTypeSpecs_();

        //     STDMETHOD(EnumUserStrings)(             // S_OK or error.
        //         HCORENUM    *phEnum,                // [IN/OUT] pointer to the enum.
        //         mdString    rStrings[],             // [OUT] put Strings here.
        //         ULONG       cmax,                   // [IN] max Strings to put.
        //         ULONG       *pcStrings) PURE;       // [OUT] put # put here.
        new void EnumUserStrings_();

        //     STDMETHOD(GetParamForMethodIndex)(      // S_OK or error.
        //         mdMethodDef md,                     // [IN] Method token.
        //         ULONG       ulParamSeq,             // [IN] Parameter sequence.
        //         mdParamDef  *ppd) PURE;             // [IN] Put Param token here.
        new void GetParamForMethodIndex_();
#endif

        //     STDMETHOD(EnumCustomAttributes)(        // S_OK or error.
        //         HCORENUM    *phEnum,                // [IN, OUT] COR enumerator.
        //         mdToken     tk,                     // [IN] Token to scope the enumeration, 0 for all.
        //         mdToken     tkType,                 // [IN] Type of interest, 0 for all.
        //         mdCustomAttribute rCustomAttributes[], // [OUT] Put custom attribute tokens here.
        //         ULONG       cMax,                   // [IN] Size of rCustomAttributes.
        //         ULONG       *pcCustomAttributes) PURE;  // [OUT, OPTIONAL] Put count of token values here.
        new void EnumCustomAttributes(ref IntPtr phEnum,
                         int tk,
                         int tkType,
                         [ComAliasName("mdCustomAttribute*")]out int mdCustomAttribute,
                         uint cMax /*must be 1*/,
                         [ComAliasName("ULONG*")]out uint pcTokens
                         );

#if !MDBG_FAKE_COM
        //     STDMETHOD(GetCustomAttributeProps)(     // S_OK or error.
        //         mdCustomAttribute cv,               // [IN] CustomAttribute token.
        //         mdToken     *ptkObj,                // [OUT, OPTIONAL] Put object token here.
        //         mdToken     *ptkType,               // [OUT, OPTIONAL] Put AttrType token here.
        //         void const  **ppBlob,               // [OUT, OPTIONAL] Put pointer to data here.
        //         ULONG       *pcbSize) PURE;         // [OUT, OPTIONAL] Put size of date here.
        new void GetCustomAttributeProps_();

        //     STDMETHOD(FindTypeRef)(   
        //         mdToken     tkResolutionScope,      // [IN] ModuleRef, AssemblyRef or TypeRef.
        //         LPCWSTR     szName,                 // [IN] TypeRef Name.
        //         mdTypeRef   *ptr) PURE;             // [OUT] matching TypeRef.
        new void FindTypeRef_();

        //     STDMETHOD(GetMemberProps)(  
        //         mdToken     mb,                     // The member for which to get props.   
        //         mdTypeDef   *pClass,                // Put member's class here. 
        //         LPWSTR      szMember,               // Put member's name here.  
        //         ULONG       cchMember,              // Size of szMember buffer in wide chars.   
        //         ULONG       *pchMember,             // Put actual size here 
        //         DWORD       *pdwAttr,               // Put flags here.  
        //         PCCOR_SIGNATURE *ppvSigBlob,        // [OUT] point to the blob value of meta data   
        //         ULONG       *pcbSigBlob,            // [OUT] actual size of signature blob  
        //         ULONG       *pulCodeRVA,            // [OUT] codeRVA    
        //         DWORD       *pdwImplFlags,          // [OUT] Impl. Flags    
        //         DWORD       *pdwCPlusTypeFlag,      // [OUT] flag for value type. selected ELEMENT_TYPE_*   
        //         void const  **ppValue,              // [OUT] constant value 
        //         ULONG       *pcchValue) PURE;       // [OUT] size of constant string in chars, 0 for non-strings.
        new void GetMemberProps_();
#endif

        //     STDMETHOD(GetFieldProps)(  
        //         mdFieldDef  mb,                     // The field for which to get props.    
        //         mdTypeDef   *pClass,                // Put field's class here.  
        //         LPWSTR      szField,                // Put field's name here.   
        //         ULONG       cchField,               // Size of szField buffer in wide chars.    
        //         ULONG       *pchField,              // Put actual size here 
        //         DWORD       *pdwAttr,               // Put flags here.  
        //         PCCOR_SIGNATURE *ppvSigBlob,        // [OUT] point to the blob value of meta data   
        //         ULONG       *pcbSigBlob,            // [OUT] actual size of signature blob  
        //         DWORD       *pdwCPlusTypeFlag,      // [OUT] flag for value type. selected ELEMENT_TYPE_*   
        //         void const  **ppValue,              // [OUT] constant value 
        //         ULONG       *pcchValue) PURE;       // [OUT] size of constant string in chars, 0 for non-strings.
        new void GetFieldProps(int mb,
                           [ComAliasName("mdTypeDef*")] out int mdTypeDef,
                           [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder szField,
                           int cchField,
                           [ComAliasName("ULONG*")] out int pchField,
                           [ComAliasName("DWORD*")] out int pdwAttr,
                           [ComAliasName("PCCOR_SIGNATURE*")] out IntPtr ppvSigBlob,
                           [ComAliasName("ULONG*")] out int pcbSigBlob,
                           [ComAliasName("DWORD*")] out int pdwCPlusTypeFlab,
                           [ComAliasName("UVCP_CONSTANT*")] out IntPtr ppValue,
                           [ComAliasName("ULONG*")] out int pcchValue
                           );

#if !MDBG_FAKE_COM
        //     STDMETHOD(GetPropertyProps)(            // S_OK, S_FALSE, or error. 
        //         mdProperty  prop,                   // [IN] property token  
        //         mdTypeDef   *pClass,                // [OUT] typedef containing the property declarion. 
        //         LPCWSTR     szProperty,             // [OUT] Property name  
        //         ULONG       cchProperty,            // [IN] the count of wchar of szProperty    
        //         ULONG       *pchProperty,           // [OUT] actual count of wchar for property name    
        //         DWORD       *pdwPropFlags,          // [OUT] property flags.    
        //         PCCOR_SIGNATURE *ppvSig,            // [OUT] property type. pointing to meta data internal blob 
        //         ULONG       *pbSig,                 // [OUT] count of bytes in *ppvSig  
        //         DWORD       *pdwCPlusTypeFlag,      // [OUT] flag for value type. selected ELEMENT_TYPE_*   
        //         void const  **ppDefaultValue,       // [OUT] constant value 
        //         ULONG       *pcchDefaultValue,      // [OUT] size of constant string in chars, 0 for non-strings.
        //         mdMethodDef *pmdSetter,             // [OUT] setter method of the property  
        //         mdMethodDef *pmdGetter,             // [OUT] getter method of the property  
        //         mdMethodDef rmdOtherMethod[],       // [OUT] other method of the property   
        //         ULONG       cMax,                   // [IN] size of rmdOtherMethod  
        //         ULONG       *pcOtherMethod) PURE;   // [OUT] total number of other method of this property
        new void GetPropertyProps_();
#endif

        //     STDMETHOD(GetParamProps)(               // S_OK or error.
        //         mdParamDef  tk,                     // [IN]The Parameter.
        //         mdMethodDef *pmd,                   // [OUT] Parent Method token.
        //         ULONG       *pulSequence,           // [OUT] Parameter sequence.
        //         LPWSTR      szName,                 // [OUT] Put name here.
        //         ULONG       cchName,                // [OUT] Size of name buffer.
        //         ULONG       *pchName,               // [OUT] Put actual size of name here.
        //         DWORD       *pdwAttr,               // [OUT] Put flags here.
        //         DWORD       *pdwCPlusTypeFlag,      // [OUT] Flag for value type. selected ELEMENT_TYPE_*.
        //         void const  **ppValue,              // [OUT] Constant value.
        //         ULONG       *pcchValue) PURE;       // [OUT] size of constant string in chars, 0 for non-strings.
        new void GetParamProps(int tk,
                           [ComAliasName("mdMethodDef*")] out int pmd,
                           [ComAliasName("ULONG*")] out uint pulSequence,
                           [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName,
                           uint cchName,
                           [ComAliasName("ULONG*")] out uint pchName,
                           [ComAliasName("DWORD*")] out uint pdwAttr,
                           [ComAliasName("DWORD*")] out uint pdwCPlusTypeFlag,
                           [ComAliasName("UVCP_CONSTANT*")] out IntPtr ppValue,
                           [ComAliasName("ULONG*")] out uint pcchValue
                           );

        //     STDMETHOD(GetCustomAttributeByName)(    // S_OK or error.
        //         mdToken     tkObj,                  // [IN] Object with Custom Attribute.
        //         LPCWSTR     szName,                 // [IN] Name of desired Custom Attribute.
        //         const void  **ppData,               // [OUT] Put pointer to data here.
        //         ULONG       *pcbData) PURE;         // [OUT] Put size of data here.
        [PreserveSig]
        new int GetCustomAttributeByName(
                            int tkObj,
                            [MarshalAs(UnmanagedType.LPWStr)]string szName,
                            out IntPtr ppData,
                            out uint pcbData);

        //     STDMETHOD_(BOOL, IsValidToken)(         // True or False.
        //         mdToken     tk) PURE;               // [IN] Given token.
        [PreserveSig] new bool IsValidToken([In, MarshalAs(UnmanagedType.U4)] uint tk);

        //     STDMETHOD(GetNestedClassProps)(         // S_OK or error.
        //         mdTypeDef   tdNestedClass,          // [IN] NestedClass token.
        //         mdTypeDef   *ptdEnclosingClass) PURE; // [OUT] EnclosingClass token.
        new void GetNestedClassProps(int tdNestedClass, [ComAliasName("mdTypeDef*")] out int tdEnclosingClass);

#if !MDBG_FAKE_COM
        //     STDMETHOD(GetNativeCallConvFromSig)(    // S_OK or error.
        //         void const  *pvSig,                 // [IN] Pointer to signature.
        //         ULONG       cbSig,                  // [IN] Count of signature bytes.
        //         ULONG       *pCallConv) PURE;       // [OUT] Put calling conv here (see CorPinvokemap).
        new void GetNativeCallConvFromSig_();
        

        //     STDMETHOD(IsGlobal)(                    // S_OK or error.
        //         mdToken     pd,                     // [IN] Type, Field, or Method token.
        //         int         *pbGlobal) PURE;        // [OUT] Put 1 if global, 0 otherwise.
        new void IsGlobal_();
#endif

        //-----------------------------------------------------------------------------
        // Begin IMetaDataImport2
        //-----------------------------------------------------------------------------
        
        /*
          STDMETHOD(EnumGenericParams)(
          HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
          mdToken      tk,                    // [IN] TypeDef or MethodDef whose generic parameters are requested
          mdGenericParam rGenericParams[],    // [OUT] Put GenericParams here.   
          ULONG       cMax,                   // [IN] Max GenericParams to put.  
          ULONG       *pcGenericParams) PURE; // [OUT] Put # put here.    
        */
        void EnumGenericParams(
                                ref IntPtr hEnum, 
                                int tk, 
                                [ComAliasName("mdGenericParam*")] out int rGenericParams, // <strip>@todo - this is a total marshalling shack. Only works if cMax == 1.</strip>
                                uint cMax, // must be 1
                                [ComAliasName("ULONG*")] out uint pcGenericParams
        );    

        //         STDMETHOD(GetGenericParamProps)(        // S_OK or error.
        //         mdGenericParam gp,                  // [IN] GenericParam
        //         ULONG        *pulParamSeq,          // [OUT] Index of the type parameter
        //         DWORD        *pdwParamFlags,        // [OUT] Flags, for future use (e.g. variance)
        //         mdToken      *ptOwner,              // [OUT] Owner (TypeDef or MethodDef)
        //         mdToken      *ptkKind,              // [OUT] For future use (e.g. non-type parameters)
        //         LPWSTR       wzname,                // [OUT] Put name here
        //         ULONG        cchName,               // [IN] Size of buffer
        //         ULONG        *pchName) PURE;        // [OUT] Put size of name (wide chars) here.
        void GetGenericParamProps(int gp,
                                  [ComAliasName("ULONG*")] out uint     pulParamSeq,
                                  [ComAliasName("DWORD*")] out int       pdwParamFlags,
                                  [ComAliasName("mdToken*")] out int       ptOwner,
                                  [ComAliasName("mdToken*")] out int       ptkKind,
                                  [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder wzName,
                                  ulong         cchName,
                                  [ComAliasName("ULONG*")] out ulong     pchName
                                  );
        
        //         STDMETHOD(GetMethodSpecProps)(
        //         mdMethodSpec mi,                    // [IN] The method instantiation
        //         mdToken *tkParent,                  // [OUT] MethodDef or MemberRef
        //         PCCOR_SIGNATURE *ppvSigBlob,        // [OUT] point to the blob value of meta data   
        //         ULONG       *pcbSigBlob) PURE;      // [OUT] actual size of signature blob  

        void GetMethodSpecProps([ComAliasName("mdMethodSpec")] int mi,
                                [ComAliasName("mdToken*")] out int tkParent,
                                [ComAliasName("PCCOR_SIGNATURE*")] out IntPtr ppvSigBlob,
                                [ComAliasName("ULONG*")] out int pcbSigBlob
                                );

#if !MDBG_FAKE_COM
        //         STDMETHOD(EnumGenericParamConstraints)(
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdGenericParam tk,                  // [IN] GenericParam whose constraints are requested
        //         mdGenericParamConstraint rGenericParamConstraints[],    // [OUT] Put GenericParamConstraints here.   
        //         ULONG       cMax,                   // [IN] Max GenericParamConstraints to put.  
        //         ULONG       *pcGenericParamConstraints) PURE; // [OUT] Put # put here.
        void EnumGenericParamConstraints_();
        
        //         STDMETHOD(GetGenericParamConstraintProps)( // S_OK or error.
        //         mdGenericParamConstraint gpc,       // [IN] GenericParamConstraint
        //         mdGenericParam *ptGenericParam,     // [OUT] GenericParam that is constrained
        //         mdToken      *ptkConstraintType) PURE; // [OUT] TypeDef/Ref/Spec constraint
        void GetGenericParamConstraintProps_();
        
        //         STDMETHOD(GetPEKind)(                   // S_OK or error.
        //         DWORD* pdwPEKind,                   // [OUT] The kind of PE (0 - not a PE)
        //         DWORD* pdwMAchine) PURE;            // [OUT] Machine as defined in NT header
        void GetPEKind_();

        //         STDMETHOD(GetVersionString)(            // S_OK or error.
        //         LPWSTR      pwzBuf,                 // [OUT[ Put version string here.
        //         DWORD       ccBufSize,              // [IN] size of the buffer, in wide chars
        //         DWORD       *pccBufSize) PURE;      // [OUT] Size of the version string, wide chars, including terminating nul.
        void GetVersionString_();

        //         STDMETHOD(EnumMethodSpecs)(
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.    
        //         mdToken      tk,                    // [IN] MethodDef or MemberRef whose MethodSpecs are requested
        //         mdMethodSpec rMethodSpecs[],        // [OUT] Put MethodSpecs here.   
        //         ULONG       cMax,                   // [IN] Max tokens to put.  
        //         ULONG       *pcMethodSpecs) PURE;   // [OUT] Put actual count here.
        void EnumMethodSpecs_();
#endif
    }

    // GUID Copied from Cor.h
    [Guid("EE62470B-E94B-424e-9B7C-2F00C9249F93"),
     InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
    ] // IID_IMetadataAssemblyImport from cor.h

    // This should be a private interface, but
    // we cannot do that becuase we are then getting an exception
    // "The specified type must be visible from COM." @ CorMetadataImport::GetRawInterface
    public interface IMetadataAssemblyImport
    {
        //     STDMETHOD(GetAssemblyProps)(            // S_OK or error.
        //         mdAssembly  mda,                    // [IN] The Assembly for which to get the properties.
        //         const void  **ppbPublicKey,         // [OUT] Pointer to the public key.
        //         ULONG       *pcbPublicKey,          // [OUT] Count of bytes in the public key.
        //         ULONG       *pulHashAlgId,          // [OUT] Hash Algorithm.
        //         LPWSTR      szName,                 // [OUT] Buffer to fill with assembly's simply name.
        //         ULONG       cchName,                // [IN] Size of buffer in wide chars.
        //         ULONG       *pchName,               // [OUT] Actual # of wide chars in name.
        //         ASSEMBLYMETADATA *pMetaData,        // [OUT] Assembly MetaData.
        //         DWORD       *pdwAssemblyFlags) PURE;    // [OUT] Flags.

        //     STDMETHOD(GetAssemblyRefProps)(         // S_OK or error.
        //         mdAssemblyRef mdar,                 // [IN] The AssemblyRef for which to get the properties.
        //         const void  **ppbPublicKeyOrToken,  // [OUT] Pointer to the public key or token.
        //         ULONG       *pcbPublicKeyOrToken,   // [OUT] Count of bytes in the public key or token.
        //         LPWSTR      szName,                 // [OUT] Buffer to fill with name.
        //         ULONG       cchName,                // [IN] Size of buffer in wide chars.
        //         ULONG       *pchName,               // [OUT] Actual # of wide chars in name.
        //         ASSEMBLYMETADATA *pMetaData,        // [OUT] Assembly MetaData.
        //         const void  **ppbHashValue,         // [OUT] Hash blob.
        //         ULONG       *pcbHashValue,          // [OUT] Count of bytes in the hash blob.
        //         DWORD       *pdwAssemblyRefFlags) PURE; // [OUT] Flags.

        //     STDMETHOD(GetFileProps)(                // S_OK or error.
        //         mdFile      mdf,                    // [IN] The File for which to get the properties.
        //         LPWSTR      szName,                 // [OUT] Buffer to fill with name.
        //         ULONG       cchName,                // [IN] Size of buffer in wide chars.
        //         ULONG       *pchName,               // [OUT] Actual # of wide chars in name.
        //         const void  **ppbHashValue,         // [OUT] Pointer to the Hash Value Blob.
        //         ULONG       *pcbHashValue,          // [OUT] Count of bytes in the Hash Value Blob.
        //         DWORD       *pdwFileFlags) PURE;    // [OUT] Flags.

        //     STDMETHOD(GetExportedTypeProps)(        // S_OK or error.
        //         mdExportedType   mdct,              // [IN] The ExportedType for which to get the properties.
        //         LPWSTR      szName,                 // [OUT] Buffer to fill with name.
        //         ULONG       cchName,                // [IN] Size of buffer in wide chars.
        //         ULONG       *pchName,               // [OUT] Actual # of wide chars in name.
        //         mdToken     *ptkImplementation,     // [OUT] mdFile or mdAssemblyRef or mdExportedType.
        //         mdTypeDef   *ptkTypeDef,            // [OUT] TypeDef token within the file.
        //         DWORD       *pdwExportedTypeFlags) PURE; // [OUT] Flags.

        //     STDMETHOD(GetManifestResourceProps)(    // S_OK or error.
        //         mdManifestResource  mdmr,           // [IN] The ManifestResource for which to get the properties.
        //         LPWSTR      szName,                 // [OUT] Buffer to fill with name.
        //         ULONG       cchName,                // [IN] Size of buffer in wide chars.
        //         ULONG       *pchName,               // [OUT] Actual # of wide chars in name.
        //         mdToken     *ptkImplementation,     // [OUT] mdFile or mdAssemblyRef that provides the ManifestResource.
        //         DWORD       *pdwOffset,             // [OUT] Offset to the beginning of the resource within the file.
        //         DWORD       *pdwResourceFlags) PURE;// [OUT] Flags.

        //     STDMETHOD(EnumAssemblyRefs)(            // S_OK or error
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.
        //         mdAssemblyRef rAssemblyRefs[],      // [OUT] Put AssemblyRefs here.
        //         ULONG       cMax,                   // [IN] Max AssemblyRefs to put.
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.

        //     STDMETHOD(EnumFiles)(                   // S_OK or error
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.
        //         mdFile      rFiles[],               // [OUT] Put Files here.
        //         ULONG       cMax,                   // [IN] Max Files to put.
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.

        //     STDMETHOD(EnumExportedTypes)(           // S_OK or error
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.
        //         mdExportedType   rExportedTypes[],  // [OUT] Put ExportedTypes here.
        //         ULONG       cMax,                   // [IN] Max ExportedTypes to put.
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.

        //     STDMETHOD(EnumManifestResources)(       // S_OK or error
        //         HCORENUM    *phEnum,                // [IN|OUT] Pointer to the enum.
        //         mdManifestResource  rManifestResources[],   // [OUT] Put ManifestResources here.
        //         ULONG       cMax,                   // [IN] Max Resources to put.
        //         ULONG       *pcTokens) PURE;        // [OUT] Put # put here.

        //     STDMETHOD(GetAssemblyFromScope)(        // S_OK or error
        //         mdAssembly  *ptkAssembly) PURE;     // [OUT] Put token here.

        //     STDMETHOD(FindExportedTypeByName)(      // S_OK or error
        //         LPCWSTR     szName,                 // [IN] Name of the ExportedType.
        //         mdToken     mdtExportedType,        // [IN] ExportedType for the enclosing class.
        //         mdExportedType   *ptkExportedType) PURE; // [OUT] Put the ExportedType token here.

        //     STDMETHOD(FindManifestResourceByName)(  // S_OK or error
        //         LPCWSTR     szName,                 // [IN] Name of the ManifestResource.
        //         mdManifestResource *ptkManifestResource) PURE;  // [OUT] Put the ManifestResource token here.

        //     STDMETHOD_(void, CloseEnum)(
        //         HCORENUM hEnum) PURE;               // Enum to be closed.

        //     STDMETHOD(FindAssembliesByName)(        // S_OK or error
        //         LPCWSTR  szAppBase,                 // [IN] optional - can be NULL
        //         LPCWSTR  szPrivateBin,              // [IN] optional - can be NULL
        //         LPCWSTR  szAssemblyName,            // [IN] required - this is the assembly you are requesting
        //         IUnknown *ppIUnk[],                 // [OUT] put IMetaDataAssemblyImport pointers here
        //         ULONG    cMax,                      // [IN] The max number to put
        //         ULONG    *pcAssemblies) PURE;       // [OUT] The number of assemblies returned.
        // };  // IMetaDataAssemblyImport
    }
}
