public void MoveTo (int rva)
		{
			if (!IsInSection (rva)) {
				code_section = reader.image.GetSectionAtVirtualAddress ((uint) rva);
				Reset (code_section.Data);
			}

			base.position = rva - (int) code_section.VirtualAddress;
		}
		public uint ResolveVirtualAddressInSection (RVA rva, Section section)
		{
			return rva + section.PointerToRawData - section.VirtualAddress;
		}
		public UserStringHeap (Section section, uint start, uint size)
			: base (section, start, size)
		{
		}
		public CodeReader (Section section, MetadataReader reader)
			: base (section.Data)
		{
			this.code_section = section;
			this.reader = reader;
		}
 public TableHeap(Section section, uint start, uint size)
     : base(section, start, size)
 {
 }
		protected Heap (Section section, uint offset, uint size)
		{
			this.Section = section;
			this.Offset = offset;
			this.Size = size;
		}
		public BlobHeap (Section section, uint start, uint size)
			: base (section, start, size)
		{
		}
		public GuidHeap (Section section, uint start, uint size)
			: base (section, start, size)
		{
		}
		void ReadMetadataStream (Section section)
		{
			// Offset		4
			uint start = metadata.VirtualAddress - section.VirtualAddress + ReadUInt32 (); // relative to the section start

			// Size			4
			uint size = ReadUInt32 ();

			var name = ReadAlignedString (16);
			switch (name) {
			case "#~":
			case "#-":
				image.TableHeap = new TableHeap (section, start, size);
				break;
			case "#Strings":
				image.StringHeap = new StringHeap (section, start, size);
				break;
			case "#Blob":
				image.BlobHeap = new BlobHeap (section, start, size);
				break;
			case "#GUID":
				image.GuidHeap = new GuidHeap (section, start, size);
				break;
			case "#US":
				image.UserStringHeap = new UserStringHeap (section, start, size);
				break;
			}
		}
		void ReadSectionData (Section section)
		{
			var position = BaseStream.Position;

			MoveTo (section.PointerToRawData);

			var length = (int) section.SizeOfRawData;
			var data = new byte [length];
			int offset = 0, read;

			while ((read = Read (data, offset, length - offset)) > 0)
				offset += read;

			section.Data = data;

			BaseStream.Position = position;
		}
		void ReadSections (ushort count)
		{
			var sections = new Section [count];

			for (int i = 0; i < count; i++) {
				var section = new Section ();

				// Name
				section.Name = ReadZeroTerminatedString (8);

				// VirtualSize		4
				Advance (4);

				// VirtualAddress	4
				section.VirtualAddress = ReadUInt32 ();
				// SizeOfRawData	4
				section.SizeOfRawData = ReadUInt32 ();
				// PointerToRawData	4
				section.PointerToRawData = ReadUInt32 ();

				// PointerToRelocations		4
				// PointerToLineNumbers		4
				// NumberOfRelocations		2
				// NumberOfLineNumbers		2
				// Characteristics			4
				Advance (16);

				sections [i] = section;

				if (section.Name == ".reloc")
					continue;

				ReadSectionData (section);
			}

			image.Sections = sections;
		}