//Retrieves the details of DLLs and entry points used by P/Invoke
        public ArrayList GetPInvokeDetails()
        {
            ArrayList externalDetails = new ArrayList();

            ImplMap   implMap   = this.peFile.tables.ImplMap;
            ModuleRef moduleRef = this.peFile.tables.ModuleRef;
            MethodDef moduleDef = this.peFile.tables.MethodDef;

            // get the name from the target type and for each type in TypeDef table check the Name for a match.
            // When the match is found, get the namespace and methodlist start and methodlist finish (by looking at the next row method list start)
            // Look at all the MethodDefs for the type, for each row look in ImplMap.memberForwarded.
            // If found, return pinvoke details.
            for (int i = 0; i < implMap.NumberOfRows; i++)
            {
                // ImplMap.MemberForwarded is a coded token with the first bit defining
                // whether it indexes the MethodDef or Field table.  As imported fields are not
                // supported it always points to the MethodDef table so we can r-shift the bits
                // to get the correct index into the methoddef table
                uint methodIndex = implMap.MemberForwarded[i] >> 1;

                string typeName   = GetTypeName(methodIndex);
                string methodName = (methodIndex > 0) ? GetStringFromStringHeap(moduleDef.Name[methodIndex - 1]) : String.Empty;

                // Get the dll name and method name
                string importedMethodName = GetStringFromStringHeap(implMap.ImportName[i]);

                // import scope points to the moduleref table
                uint   moduleRefEntry = implMap.ImportScope[i];
                string dllName        = (moduleRefEntry > 0) ? GetStringFromStringHeap(moduleRef.Name[moduleRefEntry - 1]) : String.Empty;

                externalDetails.Add(new Crossplatform.NET.PInvokeCallDetails(typeName, methodName, dllName, importedMethodName));
            }

            return(externalDetails);
        }
        public Tables(TablesHeader tablesHeader, MetaDataStream stringHeap, BinaryReader reader)
        {
            this.tablesHeader       = tablesHeader;
            this.stringHeap         = stringHeap;
            this.reader             = reader;
            this.indexSizeIndicator = tablesHeader.HeapSizes;
            this.RowsPerTable       = tablesHeader.NumberOfRows;

            // set up a table of coded index information
            // the first figure in the array is the number of bits needed to encode
            // which table the index is pointing to.  Note, some indexes use more bits
            // than are necessary, for example CustomAttributeType uses 3 bits even though
            // it only points to 2 tables, so in theory could be encoded in 1 bit.

            this.CodedIndexInformation = new object[12];
            CodedIndexInformation[(int)Tables.CodedIndexType.TypeDefOrRef]       = new int[] { 2, (int)Tables.TableName.TypeDef, (int)Tables.TableName.TypeRef, (int)Tables.TableName.TypeSpec };
            CodedIndexInformation[(int)Tables.CodedIndexType.HasConstant]        = new int[] { 2, (int)Tables.TableName.Field, (int)Tables.TableName.Param, (int)Tables.TableName.Property };
            CodedIndexInformation[(int)Tables.CodedIndexType.HasCustomAttribute] = new int[] { 5, (int)Tables.TableName.MethodDef,
                                                                                               (int)Tables.TableName.Field,
                                                                                               (int)Tables.TableName.TypeRef,
                                                                                               (int)Tables.TableName.TypeDef,
                                                                                               (int)Tables.TableName.Param,
                                                                                               (int)Tables.TableName.InterfaceImpl,
                                                                                               (int)Tables.TableName.MemberRef,
                                                                                               (int)Tables.TableName.Module,
                                                                                               (int)Tables.TableName.DeclSecurity,
                                                                                               (int)Tables.TableName.Property,
                                                                                               (int)Tables.TableName.EventX,
                                                                                               (int)Tables.TableName.StandAloneSig,
                                                                                               (int)Tables.TableName.ModuleRef,
                                                                                               (int)Tables.TableName.TypeSpec,
                                                                                               (int)Tables.TableName.Assembly,
                                                                                               (int)Tables.TableName.AssemblyRef,
                                                                                               (int)Tables.TableName.File,
                                                                                               (int)Tables.TableName.ExportedType,
                                                                                               (int)Tables.TableName.ManifestResource };
            CodedIndexInformation[(int)Tables.CodedIndexType.HasFieldMarshal]     = new int[] { 1, (int)Tables.TableName.Field, (int)Tables.TableName.Param };
            CodedIndexInformation[(int)Tables.CodedIndexType.HasDeclSecurity]     = new int[] { 2, (int)Tables.TableName.TypeDef, (int)Tables.TableName.MethodDef, (int)Tables.TableName.Assembly };
            CodedIndexInformation[(int)Tables.CodedIndexType.MemberRefParent]     = new int[] { 3, (int)Tables.TableName.TypeRef, (int)Tables.TableName.ModuleRef, (int)Tables.TableName.MethodDef, (int)Tables.TableName.TypeSpec };
            CodedIndexInformation[(int)Tables.CodedIndexType.HasSemantics]        = new int[] { 1, (int)Tables.TableName.EventX, (int)Tables.TableName.Property };
            CodedIndexInformation[(int)Tables.CodedIndexType.MethodDefOrRef]      = new int[] { 1, (int)Tables.TableName.MethodDef, (int)Tables.TableName.MemberRef };
            CodedIndexInformation[(int)Tables.CodedIndexType.MemberForwarded]     = new int[] { 1, (int)Tables.TableName.Field, (int)Tables.TableName.MethodDef };
            CodedIndexInformation[(int)Tables.CodedIndexType.Implementation]      = new int[] { 2, (int)Tables.TableName.File, (int)Tables.TableName.AssemblyRef, (int)Tables.TableName.ExportedType };
            CodedIndexInformation[(int)Tables.CodedIndexType.CustomAttributeType] = new int[] { 3, (int)Tables.TableName.MethodDef, (int)Tables.TableName.MemberRef };
            CodedIndexInformation[(int)Tables.CodedIndexType.ResolutionScope]     = new int[] { 2, (int)Tables.TableName.Module, (int)Tables.TableName.ModuleRef, (int)Tables.TableName.AssemblyRef, (int)Tables.TableName.TypeRef };

            this.Module          = new Module(Tables.TableName.Module, this);
            this.TypeRef         = new TypeRef(Tables.TableName.TypeRef, this);
            this.TypeDef         = new TypeDef(Tables.TableName.TypeDef, this);
            this.Field           = new Field(Tables.TableName.Field, this);
            this.MethodDef       = new MethodDef(Tables.TableName.MethodDef, this);
            this.Param           = new Param(Tables.TableName.Param, this);
            this.InterfaceImpl   = new InterfaceImpl(Tables.TableName.InterfaceImpl, this);
            this.MemberRef       = new MemberRef(Tables.TableName.MemberRef, this);
            this.Constant        = new Constant(Tables.TableName.Constant, this);
            this.CustomAttribute = new CustomAttribute(Tables.TableName.CustomAttribute, this);
            this.FieldMarshal    = new FieldMarshal(Tables.TableName.FieldMarshal, this);
            this.DeclSecurity    = new DeclSecurity(Tables.TableName.DeclSecurity, this);
            this.ClassLayout     = new ClassLayout(Tables.TableName.ClassLayout, this);
            this.FieldLayout     = new FieldLayout(Tables.TableName.FieldLayout, this);
            this.StandAloneSig   = new StandAloneSig(Tables.TableName.StandAloneSig, this);
            this.EventMap        = new EventMap(Tables.TableName.EventMap, this);
            this.EventX          = new EventX(Tables.TableName.EventX, this);
            this.PropertyMap     = new PropertyMap(Tables.TableName.PropertyMap, this);
            this.Property        = new Property(Tables.TableName.Property, this);
            this.MethodSemantics = new MethodSemantics(Tables.TableName.MethodSemantics, this);
            this.MethodImpl      = new MethodImpl(Tables.TableName.MethodImpl, this);
            this.ModuleRef       = new ModuleRef(Tables.TableName.ModuleRef, this);
            this.TypeSpec        = new TypeSpec(Tables.TableName.TypeSpec, this);
            this.ImplMap         = new ImplMap(Tables.TableName.ImplMap, this);
        }