private void ReadAndInitializeRowCounts(BinaryStreamReader reader, ulong validMask)
        {
            var tables = new Array[45];

            if ((validMask & ((ulong)1 << (int)TableKind.Module)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new ModuleEntry[rowCount];
                tables[(int)TableKind.Module] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.TypeRef)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new TypeRefEntry[rowCount];
                tables[(int)TableKind.TypeRef] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.TypeDef)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new TypeDefEntry[rowCount];
                tables[(int)TableKind.TypeDef] = table;
            }

            if ((validMask & ((ulong)1 << 0x03)) != 0)
                throw new BadImageFormatException("Non-standard metadata table 0x"+validMask.ToString("X2")+".");
            if ((validMask & ((ulong)1 << (int)TableKind.Field)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new FieldEntry[rowCount];
                tables[(int)TableKind.Field] = table;
            }

            if ((validMask & ((ulong)1 << 0x05)) != 0)
                throw new BadImageFormatException("Non-standard metadata table 0x"+validMask.ToString("X2")+".");
            if ((validMask & ((ulong)1 << (int)TableKind.MethodDef)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new MethodDefEntry[rowCount];
                tables[(int)TableKind.MethodDef] = table;
            }

            if ((validMask & ((ulong)1 << 0x07)) != 0)
                throw new BadImageFormatException("Non-standard metadata table 0x"+validMask.ToString("X2")+".");
            if ((validMask & ((ulong)1 << (int)TableKind.Param)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new ParamEntry[rowCount];
                tables[(int)TableKind.Param] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.InterfaceImpl)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new InterfaceImplEntry[rowCount];
                tables[(int)TableKind.InterfaceImpl] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.MemberRef)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new MemberRefEntry[rowCount];
                tables[(int)TableKind.MemberRef] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.Constant)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new ConstantEntry[rowCount];
                tables[(int)TableKind.Constant] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.CustomAttribute)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new CustomAttributeEntry[rowCount];
                tables[(int)TableKind.CustomAttribute] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.FieldMarshal)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new FieldMarshalEntry[rowCount];
                tables[(int)TableKind.FieldMarshal] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.DeclSecurity)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new DeclSecurityEntry[rowCount];
                tables[(int)TableKind.DeclSecurity] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.ClassLayout)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new ClassLayoutEntry[rowCount];
                tables[(int)TableKind.ClassLayout] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.FieldLayout)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new FieldLayoutEntry[rowCount];
                tables[(int)TableKind.FieldLayout] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.StandAloneSig)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new StandAloneSigEntry[rowCount];
                tables[(int)TableKind.StandAloneSig] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.EventMap)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new EventMapEntry[rowCount];
                tables[(int)TableKind.EventMap] = table;
            }

            if ((validMask & ((ulong)1 << 0x13)) != 0)
                throw new BadImageFormatException("Non-standard metadata table 0x"+validMask.ToString("X2")+".");
            if ((validMask & ((ulong)1 << (int)TableKind.Event)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new EventEntry[rowCount];
                tables[(int)TableKind.Event] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.PropertyMap)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new PropertyMapEntry[rowCount];
                tables[(int)TableKind.PropertyMap] = table;
            }

            if ((validMask & ((ulong)1 << 0x16)) != 0)
                throw new BadImageFormatException("Non-standard metadata table 0x"+validMask.ToString("X2")+".");
            if ((validMask & ((ulong)1 << (int)TableKind.Property)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new PropertyEntry[rowCount];
                tables[(int)TableKind.Property] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.MethodSemantics)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new MethodSemanticsEntry[rowCount];
                tables[(int)TableKind.MethodSemantics] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.MethodImpl)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new MethodImplEntry[rowCount];
                tables[(int)TableKind.MethodImpl] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.ModuleRef)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new ModuleRefEntry[rowCount];
                tables[(int)TableKind.ModuleRef] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.TypeSpec)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new TypeSpecEntry[rowCount];
                tables[(int)TableKind.TypeSpec] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.ImplMap)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new ImplMapEntry[rowCount];
                tables[(int)TableKind.ImplMap] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.FieldRVA)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new FieldRVAEntry[rowCount];
                tables[(int)TableKind.FieldRVA] = table;
            }

            if ((validMask & ((ulong)1 << 0x1E)) != 0)
                throw new BadImageFormatException("Non-standard metadata table 0x"+validMask.ToString("X2")+".");
            if ((validMask & ((ulong)1 << 0x1F)) != 0)
                throw new BadImageFormatException("Non-standard metadata table 0x"+validMask.ToString("X2")+".");
            if ((validMask & ((ulong)1 << (int)TableKind.Assembly)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new AssemblyEntry[rowCount];
                tables[(int)TableKind.Assembly] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.AssemblyProcessor)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new AssemblyProcessorEntry[rowCount];
                tables[(int)TableKind.AssemblyProcessor] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.AssemblyOS)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new AssemblyOSEntry[rowCount];
                tables[(int)TableKind.AssemblyOS] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.AssemblyRef)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new AssemblyRefEntry[rowCount];
                tables[(int)TableKind.AssemblyRef] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.AssemblyRefProcessor)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new AssemblyRefProcessorEntry[rowCount];
                tables[(int)TableKind.AssemblyRefProcessor] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.AssemblyRefOS)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new AssemblyRefOSEntry[rowCount];
                tables[(int)TableKind.AssemblyRefOS] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.File)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new FileEntry[rowCount];
                tables[(int)TableKind.File] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.ExportedType)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new ExportedTypeEntry[rowCount];
                tables[(int)TableKind.ExportedType] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.ManifestResource)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new ManifestResourceEntry[rowCount];
                tables[(int)TableKind.ManifestResource] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.NestedClass)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new NestedClassEntry[rowCount];
                tables[(int)TableKind.NestedClass] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.GenericParam)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new GenericParamEntry[rowCount];
                tables[(int)TableKind.GenericParam] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.MethodSpec)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new MethodSpecEntry[rowCount];
                tables[(int)TableKind.MethodSpec] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.GenericParamConstraint)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var table = new GenericParamConstraintEntry[rowCount];
                tables[(int)TableKind.GenericParamConstraint] = table;
            }

            ulong trailingZeroesMask = ulong.MaxValue << 45;
            if ((validMask & trailingZeroesMask) != 0)
                throw new BadImageFormatException("Non-standard metadata table bits.");

            this.Tables = tables;
        }
        private void ReadAndInitializeRowCounts(BinaryStreamReader reader, ulong validMask)
        {
            var tables = new Array[45];

            if ((validMask & ((ulong)1 << (int)TableKind.Module)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new ModuleEntry[rowCount];
                tables[(int)TableKind.Module] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.TypeRef)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new TypeRefEntry[rowCount];
                tables[(int)TableKind.TypeRef] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.TypeDef)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new TypeDefEntry[rowCount];
                tables[(int)TableKind.TypeDef] = table;
            }

            if ((validMask & ((ulong)1 << 0x03)) != 0)
            {
                throw new BadImageFormatException("Non-standard metadata table 0x" + validMask.ToString("X2") + ".");
            }
            if ((validMask & ((ulong)1 << (int)TableKind.Field)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new FieldEntry[rowCount];
                tables[(int)TableKind.Field] = table;
            }

            if ((validMask & ((ulong)1 << 0x05)) != 0)
            {
                throw new BadImageFormatException("Non-standard metadata table 0x" + validMask.ToString("X2") + ".");
            }
            if ((validMask & ((ulong)1 << (int)TableKind.MethodDef)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new MethodDefEntry[rowCount];
                tables[(int)TableKind.MethodDef] = table;
            }

            if ((validMask & ((ulong)1 << 0x07)) != 0)
            {
                throw new BadImageFormatException("Non-standard metadata table 0x" + validMask.ToString("X2") + ".");
            }
            if ((validMask & ((ulong)1 << (int)TableKind.Param)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new ParamEntry[rowCount];
                tables[(int)TableKind.Param] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.InterfaceImpl)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new InterfaceImplEntry[rowCount];
                tables[(int)TableKind.InterfaceImpl] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.MemberRef)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new MemberRefEntry[rowCount];
                tables[(int)TableKind.MemberRef] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.Constant)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new ConstantEntry[rowCount];
                tables[(int)TableKind.Constant] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.CustomAttribute)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new CustomAttributeEntry[rowCount];
                tables[(int)TableKind.CustomAttribute] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.FieldMarshal)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new FieldMarshalEntry[rowCount];
                tables[(int)TableKind.FieldMarshal] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.DeclSecurity)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new DeclSecurityEntry[rowCount];
                tables[(int)TableKind.DeclSecurity] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.ClassLayout)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new ClassLayoutEntry[rowCount];
                tables[(int)TableKind.ClassLayout] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.FieldLayout)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new FieldLayoutEntry[rowCount];
                tables[(int)TableKind.FieldLayout] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.StandAloneSig)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new StandAloneSigEntry[rowCount];
                tables[(int)TableKind.StandAloneSig] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.EventMap)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new EventMapEntry[rowCount];
                tables[(int)TableKind.EventMap] = table;
            }

            if ((validMask & ((ulong)1 << 0x13)) != 0)
            {
                throw new BadImageFormatException("Non-standard metadata table 0x" + validMask.ToString("X2") + ".");
            }
            if ((validMask & ((ulong)1 << (int)TableKind.Event)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new EventEntry[rowCount];
                tables[(int)TableKind.Event] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.PropertyMap)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new PropertyMapEntry[rowCount];
                tables[(int)TableKind.PropertyMap] = table;
            }

            if ((validMask & ((ulong)1 << 0x16)) != 0)
            {
                throw new BadImageFormatException("Non-standard metadata table 0x" + validMask.ToString("X2") + ".");
            }
            if ((validMask & ((ulong)1 << (int)TableKind.Property)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new PropertyEntry[rowCount];
                tables[(int)TableKind.Property] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.MethodSemantics)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new MethodSemanticsEntry[rowCount];
                tables[(int)TableKind.MethodSemantics] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.MethodImpl)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new MethodImplEntry[rowCount];
                tables[(int)TableKind.MethodImpl] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.ModuleRef)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new ModuleRefEntry[rowCount];
                tables[(int)TableKind.ModuleRef] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.TypeSpec)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new TypeSpecEntry[rowCount];
                tables[(int)TableKind.TypeSpec] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.ImplMap)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new ImplMapEntry[rowCount];
                tables[(int)TableKind.ImplMap] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.FieldRVA)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new FieldRVAEntry[rowCount];
                tables[(int)TableKind.FieldRVA] = table;
            }

            if ((validMask & ((ulong)1 << 0x1E)) != 0)
            {
                throw new BadImageFormatException("Non-standard metadata table 0x" + validMask.ToString("X2") + ".");
            }
            if ((validMask & ((ulong)1 << 0x1F)) != 0)
            {
                throw new BadImageFormatException("Non-standard metadata table 0x" + validMask.ToString("X2") + ".");
            }
            if ((validMask & ((ulong)1 << (int)TableKind.Assembly)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new AssemblyEntry[rowCount];
                tables[(int)TableKind.Assembly] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.AssemblyProcessor)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new AssemblyProcessorEntry[rowCount];
                tables[(int)TableKind.AssemblyProcessor] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.AssemblyOS)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new AssemblyOSEntry[rowCount];
                tables[(int)TableKind.AssemblyOS] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.AssemblyRef)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new AssemblyRefEntry[rowCount];
                tables[(int)TableKind.AssemblyRef] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.AssemblyRefProcessor)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new AssemblyRefProcessorEntry[rowCount];
                tables[(int)TableKind.AssemblyRefProcessor] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.AssemblyRefOS)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new AssemblyRefOSEntry[rowCount];
                tables[(int)TableKind.AssemblyRefOS] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.File)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new FileEntry[rowCount];
                tables[(int)TableKind.File] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.ExportedType)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new ExportedTypeEntry[rowCount];
                tables[(int)TableKind.ExportedType] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.ManifestResource)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new ManifestResourceEntry[rowCount];
                tables[(int)TableKind.ManifestResource] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.NestedClass)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new NestedClassEntry[rowCount];
                tables[(int)TableKind.NestedClass] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.GenericParam)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new GenericParamEntry[rowCount];
                tables[(int)TableKind.GenericParam] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.MethodSpec)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new MethodSpecEntry[rowCount];
                tables[(int)TableKind.MethodSpec] = table;
            }

            if ((validMask & ((ulong)1 << (int)TableKind.GenericParamConstraint)) != 0)
            {
                uint rowCount = reader.ReadUInt32();
                var  table    = new GenericParamConstraintEntry[rowCount];
                tables[(int)TableKind.GenericParamConstraint] = table;
            }


            ulong trailingZeroesMask = ulong.MaxValue << 45;

            if ((validMask & trailingZeroesMask) != 0)
            {
                throw new BadImageFormatException("Non-standard metadata table bits.");
            }

            this.Tables = tables;
        }