void ReadAllFields()
        {
            TypeDefTable tdefTable = m_tableReader.GetTypeDefTable();

            if (!m_tHeap.HasTable(FieldTable.RId))
            {
                m_fields = new FieldDefinition [0];
                return;
            }

            FieldTable fldTable = m_tableReader.GetFieldTable();

            m_fields = new FieldDefinition [fldTable.Rows.Count];

            for (int i = 0; i < m_typeDefs.Length; i++)
            {
                TypeDefinition dec     = m_typeDefs [i];
                GenericContext context = new GenericContext(dec);

                int index = i, next;

                if (index == tdefTable.Rows.Count - 1)
                {
                    next = fldTable.Rows.Count + 1;
                }
                else
                {
                    next = (int)(tdefTable [index + 1]).FieldList;
                }

                for (int j = (int)tdefTable [index].FieldList; j < next; j++)
                {
                    FieldRow        frow = fldTable [j - 1];
                    FieldSig        fsig = m_sigReader.GetFieldSig(frow.Signature);
                    FieldDefinition fdef = new FieldDefinition(
                        m_root.Streams.StringsHeap [frow.Name],
                        this.GetTypeRefFromSig(fsig.Type, context), frow.Flags);
                    fdef.MetadataToken = MetadataToken.FromMetadataRow(TokenType.Field, j - 1);

                    if (fsig.CustomMods.Length > 0)
                    {
                        fdef.FieldType = GetModifierType(fsig.CustomMods, fdef.FieldType);
                    }

                    dec.Fields.Add(fdef);
                    m_fields [j - 1] = fdef;
                }
            }
        }
        void CompleteMethods()
        {
            TypeDefTable tdefTable = m_tableReader.GetTypeDefTable();

            if (!m_tHeap.HasTable(MethodTable.RId))
            {
                m_meths = new MethodDefinition [0];
                return;
            }

            MethodTable methTable  = m_tableReader.GetMethodTable();
            ParamTable  paramTable = m_tableReader.GetParamTable();

            if (!m_tHeap.HasTable(ParamTable.RId))
            {
                m_parameters = new ParameterDefinition [0];
            }
            else
            {
                m_parameters = new ParameterDefinition [paramTable.Rows.Count];
            }

            for (int i = 0; i < m_typeDefs.Length; i++)
            {
                TypeDefinition dec = m_typeDefs [i];

                int index = i, next;

                if (index == tdefTable.Rows.Count - 1)
                {
                    next = methTable.Rows.Count + 1;
                }
                else
                {
                    next = (int)(tdefTable [index + 1]).MethodList;
                }

                for (int j = (int)tdefTable [index].MethodList; j < next; j++)
                {
                    MethodRow        methRow = methTable [j - 1];
                    MethodDefinition mdef    = m_meths [j - 1];
                    if (mdef.IsConstructor)
                    {
                        dec.Constructors.Add(mdef);
                    }
                    else
                    {
                        dec.Methods.Add(mdef);
                    }
                    GenericContext context = new GenericContext(mdef);

                    MethodDefSig msig = m_sigReader.GetMethodDefSig(methRow.Signature);
                    mdef.HasThis           = msig.HasThis;
                    mdef.ExplicitThis      = msig.ExplicitThis;
                    mdef.CallingConvention = msig.MethCallConv;

                    int prms;
                    if (j == methTable.Rows.Count)
                    {
                        prms = m_parameters.Length + 1;
                    }
                    else
                    {
                        prms = (int)(methTable [j]).ParamList;
                    }

                    ParameterDefinition retparam = null;

                    //TODO: optimize this
                    ParamRow pRow  = null;
                    int      start = (int)methRow.ParamList - 1;

                    if (paramTable != null && start < prms - 1)
                    {
                        pRow = paramTable [start];
                    }

                    if (pRow != null && pRow.Sequence == 0)                       // ret type
                    {
                        retparam = new ParameterDefinition(
                            m_root.Streams.StringsHeap [pRow.Name],
                            0,
                            pRow.Flags,
                            null);
                        retparam.Method      = mdef;
                        m_parameters [start] = retparam;
                        start++;
                    }

                    for (int k = 0; k < msig.ParamCount; k++)
                    {
                        int pointer = start + k;

                        if (paramTable != null && pointer < prms - 1)
                        {
                            pRow = paramTable [pointer];
                        }

                        Param psig = msig.Parameters [k];

                        ParameterDefinition pdef;
                        if (pRow != null)
                        {
                            pdef = BuildParameterDefinition(
                                m_root.Streams.StringsHeap [pRow.Name],
                                pRow.Sequence, pRow.Flags, psig, context);
                            pdef.MetadataToken     = MetadataToken.FromMetadataRow(TokenType.Param, pointer);
                            m_parameters [pointer] = pdef;
                        }
                        else
                        {
                            pdef = BuildParameterDefinition(
                                string.Concat("A_", mdef.IsStatic ? k : k + 1),
                                k + 1, (ParamAttributes)0, psig, context);
                        }

                        pdef.Method = mdef;
                        mdef.Parameters.Add(pdef);
                    }

                    mdef.ReturnType = GetMethodReturnType(msig, context);
                    MethodReturnType mrt = mdef.ReturnType as MethodReturnType;
                    mrt.Method = mdef;
                    if (retparam != null)
                    {
                        mrt.Parameter = retparam;
                        mrt.Parameter.ParameterType = mrt.ReturnType;
                    }
                }
            }

            uint eprid = CodeReader.GetRid((int)m_reader.Image.CLIHeader.EntryPointToken);

            if (eprid > 0 && eprid <= m_meths.Length)
            {
                m_module.Assembly.EntryPoint = GetMethodDefAt(eprid);
            }
        }
        public override void VisitTypeDefinitionCollection(TypeDefinitionCollection types)
        {
            // type def reading
            TypeDefTable typesTable = m_tableReader.GetTypeDefTable();

            m_typeDefs = new TypeDefinition [typesTable.Rows.Count];
            for (int i = 0; i < typesTable.Rows.Count; i++)
            {
                TypeDefRow     type = typesTable [i];
                TypeDefinition t    = new TypeDefinition(
                    m_root.Streams.StringsHeap [type.Name],
                    m_root.Streams.StringsHeap [type.Namespace],
                    type.Flags);
                t.MetadataToken = MetadataToken.FromMetadataRow(TokenType.TypeDef, i);

                m_typeDefs [i] = t;
            }

            // nested types
            if (m_tHeap.HasTable(NestedClassTable.RId))
            {
                NestedClassTable nested = m_tableReader.GetNestedClassTable();
                for (int i = 0; i < nested.Rows.Count; i++)
                {
                    NestedClassRow row = nested [i];

                    TypeDefinition parent = GetTypeDefAt(row.EnclosingClass);
                    TypeDefinition child  = GetTypeDefAt(row.NestedClass);

                    parent.NestedTypes.Add(child);
                }
            }

            foreach (TypeDefinition type in m_typeDefs)
            {
                types.Add(type);
            }

            // type ref reading
            if (m_tHeap.HasTable(TypeRefTable.RId))
            {
                TypeRefTable typesRef = m_tableReader.GetTypeRefTable();

                m_typeRefs = new TypeReference [typesRef.Rows.Count];

                for (int i = 0; i < typesRef.Rows.Count; i++)
                {
                    AddTypeRef(typesRef, i);
                }
            }
            else
            {
                m_typeRefs = new TypeReference [0];
            }

            ReadTypeSpecs();
            ReadMethodSpecs();

            ReadMethods();
            ReadGenericParameters();

            // set base types
            for (int i = 0; i < typesTable.Rows.Count; i++)
            {
                TypeDefRow     type  = typesTable [i];
                TypeDefinition child = m_typeDefs [i];
                child.BaseType = GetTypeDefOrRef(type.Extends, new GenericContext(child));
            }

            CompleteMethods();
            ReadAllFields();
            ReadMemberReferences();
        }