void AddMethods(SharpAssembly_ asm, TypeDef[] typeDefTable, uint index)
        {
            Method[] methodDefTable = asm.Tables.Method;
            if (methodDefTable == null) {
                return;
            }

            uint methodIndexStart = typeDefTable[index].MethodList;

            // 0 means no methods
            if (methodIndexStart == 0) {
                return;
            }

            uint methodIndexEnd   = (uint)methodDefTable.GetUpperBound(0);
            if (index < typeDefTable.GetUpperBound(0)) {
                methodIndexEnd = typeDefTable[index + 1].MethodList;
            }

            for (uint i = methodIndexStart; i < methodIndexEnd; ++i) {
                IMethod newMethod = new SharpAssemblyMethod(asm, methodDefTable, this, i);
                methods.Add(newMethod);
            }
        }
        /// <summary>
        /// The constructor is private because the only way to construct SharpAssemblyClass objects
        /// is to call FromTypeRef/Def to make us of the cache
        /// </summary>
        private SharpAssemblyClass(SharpAssembly_ assembly, TypeDef[] typeDefTable, uint index)
        {
            if (assembly == null) {
                throw new System.ArgumentNullException("assembly");
            }
            if (typeDefTable == null) {
                throw new System.ArgumentNullException("typeDefTable");
            }
            if (index > typeDefTable.GetUpperBound(0) || index < 1) {
                throw new System.ArgumentOutOfRangeException("index", index, String.Format("must be between 1 and {0}!", typeDefTable.GetUpperBound(0)));
            }

            TypeDef typeDef = typeDefTable[index];
            typeDefIndex = index;  // store index for use in LoadMembers()

            declaredIn = assembly;

            FullyQualifiedName = GetNestedName(assembly, typeDefTable, index);

            // store in assembly's cache
            assembly.TypeDefObjects[index] = this;

            if (typeDef.IsFlagSet(TypeDef.FLAG_INTERFACE)) {
                classType = ClassType.Interface;
            } else if (typeDef.IsFlagSet(TypeDef.FLAG_CLASS)) {
                classType = ClassType.Class;
            }

            if (typeDef.Extends == 0) goto noext;

            SharpAssemblyClass extend = GetTypeRefOrDefClass(assembly, typeDef.Extends);

            if (extend == null) goto noext;

            if (extend.FullyQualifiedName == "System.Enum") {
                classType = ClassType.Enum;
            } else if (extend.FullyQualifiedName == "System.ValueType") {
                classType = ClassType.Struct;
            }

            baseTypeCollection.Add(extend);

            if (IsSubclassOf("System.Delegate")) classType = ClassType.Delegate;

            noext:

            InterfaceImpl[] ifaces = assembly.Tables.InterfaceImpl;
            if (ifaces == null) goto nointerfaces;

            for (int i = 1; i <= ifaces.GetUpperBound(0); ++i) {
                if (ifaces[i].Class == index) {
                    SharpAssemblyClass impl = GetTypeRefOrDefClass(assembly, ifaces[i].Interface);
                    if (impl != null) {
                        baseTypeCollection.Add(impl);
                    }
                }
            }

            nointerfaces:

            NestedClass[] nestedClasses = assembly.Tables.NestedClass;
            if (nestedClasses == null) goto nonested;

            for (int i = 1; i <= nestedClasses.GetUpperBound(0); ++i) {
                if (nestedClasses[i].EnclosingClass == index) {
                    IClass newclass = FromTypeDef(assembly, nestedClasses[i].NestedClassIndex);
                    innerClasses.Add(newclass);
                }
            }

            nonested:

            // Attributes
            ArrayList attrib = assembly.Attributes.TypeDef[index] as ArrayList;
            if (attrib == null) goto modifiers;

            AbstractAttributeSection sect = new AbstractAttributeSection();

            foreach(SharpCustomAttribute customattribute in attrib) {
                sect.Attributes.Add(new SharpAssemblyAttribute(assembly, customattribute));
            }

            attributes.Add(sect);

            modifiers:

            modifiers = ModifierEnum.None;

            if (typeDef.IsFlagSet(TypeDef.FLAG_SEALED)) {
                modifiers |= ModifierEnum.Sealed;
            }

            if (typeDef.IsFlagSet(TypeDef.FLAG_ABSTRACT)) {
                modifiers |= ModifierEnum.Abstract;
            }

            if (typeDef.IsMaskedFlagSet(TypeDef.FLAG_NESTEDPRIVATE, TypeDef.FLAG_VISIBILITYMASK)) {
                modifiers |= ModifierEnum.Private;
            } else if (typeDef.IsMaskedFlagSet(TypeDef.FLAG_NESTEDPUBLIC, TypeDef.FLAG_VISIBILITYMASK) || typeDef.IsMaskedFlagSet(TypeDef.FLAG_PUBLIC, TypeDef.FLAG_VISIBILITYMASK)) {
                modifiers |= ModifierEnum.Public;
            } else if (typeDef.IsMaskedFlagSet(TypeDef.FLAG_NESTEDASSEMBLY, TypeDef.FLAG_VISIBILITYMASK) ||
                typeDef.IsMaskedFlagSet(TypeDef.FLAG_NOTPUBLIC, TypeDef.FLAG_VISIBILITYMASK)) {
                modifiers |= ModifierEnum.Internal;
            } else if (typeDef.IsMaskedFlagSet(TypeDef.FLAG_NESTEDFAMILY, TypeDef.FLAG_VISIBILITYMASK)) {
                modifiers |= ModifierEnum.Protected;
            } else if (typeDef.IsMaskedFlagSet(TypeDef.FLAG_NESTEDFAMORASSEM, TypeDef.FLAG_VISIBILITYMASK)) {
                modifiers |= ModifierEnum.ProtectedOrInternal;
            } else if (typeDef.IsMaskedFlagSet(TypeDef.FLAG_NESTEDFAMANDASSEM, TypeDef.FLAG_VISIBILITYMASK)) {
                modifiers |= ModifierEnum.Protected;
                modifiers |= ModifierEnum.Internal;
            }

            if (typeDef.IsFlagSet(TypeDef.FLAG_SPECIALNAME)) {
                modifiers |= ModifierEnum.SpecialName;
            }

            /* members are loaded on demand now
            if (classType != ClassType.Delegate && loadMembers) {
                AddMethods(assembly, typeDefTable, index);
                AddFields(assembly, typeDefTable, index);
                AddProperties(assembly, typeDefTable, index);
                AddEvents(assembly, typeDefTable, index);

                membersLoaded = true;
            }
            */
        }
        void AddFields(SharpAssembly_ asm, TypeDef[] typeDefTable, uint index)
        {
            Field[] fieldTable = asm.Tables.Field;
            if (fieldTable == null) {
                return;
            }

            uint fieldIndexStart = typeDefTable[index].FieldList;

            // 0 means no fields
            if (fieldIndexStart == 0) {
                return;
            }

            uint fieldIndexEnd   = (uint)fieldTable.GetUpperBound(0);
            if (index < typeDefTable.GetUpperBound(0)) {
                fieldIndexEnd = typeDefTable[index + 1].FieldList;
            }

            for (uint i = fieldIndexStart; i < fieldIndexEnd; ++i) {
                IField newField = new SharpAssemblyField(asm, fieldTable, this, i);
                fields.Add(newField);
            }
        }