/// <summary>
        /// Initializes MD tables
        /// </summary>
        /// <param name="peImage">The PEImage</param>
        public void Initialize(IPEImage peImage)
        {
            reserved1    = imageStream.ReadUInt32();
            majorVersion = imageStream.ReadByte();
            minorVersion = imageStream.ReadByte();
            flags        = (MDStreamFlags)imageStream.ReadByte();
            log2Rid      = imageStream.ReadByte();
            validMask    = imageStream.ReadUInt64();
            sortedMask   = imageStream.ReadUInt64();

            int maxPresentTables;
            var dnTableSizes = new DotNetTableSizes();
            var tableInfos   = dnTableSizes.CreateTables(majorVersion, minorVersion, out maxPresentTables);

            mdTables = new MDTable[tableInfos.Length];

            ulong valid = validMask;
            var   sizes = new uint[64];

            for (int i = 0; i < 64; valid >>= 1, i++)
            {
                uint rows = (valid & 1) == 0 ? 0 : imageStream.ReadUInt32();
                if (i >= maxPresentTables)
                {
                    rows = 0;
                }
                sizes[i] = rows;
                if (i < mdTables.Length)
                {
                    mdTables[i] = new MDTable((Table)i, rows, tableInfos[i]);
                }
            }

            if (HasExtraData)
            {
                extraData = imageStream.ReadUInt32();
            }

            dnTableSizes.InitializeSizes(HasBigStrings, HasBigGUID, HasBigBlob, sizes);

            var currentRva = peImage.ToRVA(imageStream.FileOffset) + (uint)imageStream.Position;

            foreach (var mdTable in mdTables)
            {
                var dataLen = (long)mdTable.TableInfo.RowSize * (long)mdTable.Rows;
                mdTable.ImageStream = peImage.CreateStream(currentRva, dataLen);
                var newRva = currentRva + (uint)dataLen;
                if (newRva < currentRva)
                {
                    throw new BadImageFormatException("Too big MD table");
                }
                currentRva = newRva;
            }

            InitializeTables();
        }
		/// <summary>
		/// Initializes MD tables
		/// </summary>
		/// <param name="peImage">The PEImage</param>
		public void Initialize(IPEImage peImage) {
			if (initialized)
				throw new Exception("Initialize() has already been called");
			initialized = true;

			reserved1 = imageStream.ReadUInt32();
			majorVersion = imageStream.ReadByte();
			minorVersion = imageStream.ReadByte();
			flags = (MDStreamFlags)imageStream.ReadByte();
			log2Rid = imageStream.ReadByte();
			validMask = imageStream.ReadUInt64();
			sortedMask = imageStream.ReadUInt64();

			int maxPresentTables;
			var dnTableSizes = new DotNetTableSizes();
			var tableInfos = dnTableSizes.CreateTables(majorVersion, minorVersion, out maxPresentTables);
			mdTables = new MDTable[tableInfos.Length];

			ulong valid = validMask;
			var sizes = new uint[64];
			for (int i = 0; i < 64; valid >>= 1, i++) {
				uint rows = (valid & 1) == 0 ? 0 : imageStream.ReadUInt32();
				if (i >= maxPresentTables)
					rows = 0;
				sizes[i] = rows;
				if (i < mdTables.Length)
					mdTables[i] = new MDTable((Table)i, rows, tableInfos[i]);
			}

			if (HasExtraData)
				extraData = imageStream.ReadUInt32();

			dnTableSizes.InitializeSizes(HasBigStrings, HasBigGUID, HasBigBlob, sizes);

			var currentRva = peImage.ToRVA(imageStream.FileOffset) + (uint)imageStream.Position;
			foreach (var mdTable in mdTables) {
				var dataLen = (long)mdTable.TableInfo.RowSize * (long)mdTable.Rows;
				mdTable.ImageStream = peImage.CreateStream(currentRva, dataLen);
				var newRva = currentRva + (uint)dataLen;
				if (newRva < currentRva)
					throw new BadImageFormatException("Too big MD table");
				currentRva = newRva;
			}

			InitializeTables();
		}