context: //
  // MetadataSystem.cs
  //
  // Author:
  //   Jb Evain (jbevain@gmail.com)
  //
  // Copyright (c) 2008 - 2011 Jb Evain
  //
  // Permission is hereby granted, free of charge, to any person obtaining
  // a copy of this software and associated documentation files (the
  // "Software"), to deal in the Software without restriction, including
  // without limitation the rights to use, copy, modify, merge, publish,
  // distribute, sublicense, and/or sell copies of the Software, and to
  // permit persons to whom the Software is furnished to do so, subject to
  // the following conditions:
  //
  // The above copyright notice and this permission notice shall be
  // included in all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  //
  
  using System;
  using System.Collections.Generic;
  
  using Mono.Cecil.Metadata;
  
  namespace Mono.Cecil {
  
  	struct Range {
  		public uint Start;
  		public uint Length;
  
  		public Range (uint index, uint length)
  		{
  			this.Start = index;
  			this.Length = length;
  		}
  	}
  
  	sealed class MetadataSystem {
  
  		internal AssemblyNameReference [] AssemblyReferences;
  		internal ModuleReference [] ModuleReferences;
  
  		internal TypeDefinition [] Types;
  		internal TypeReference [] TypeReferences;
  
  		internal FieldDefinition [] Fields;
  		internal MethodDefinition [] Methods;
  		internal MemberReference [] MemberReferences;
  
  		internal Dictionary<uint, uint []> NestedTypes;
  		internal Dictionary<uint, uint> ReverseNestedTypes;
  		internal Dictionary<uint, MetadataToken []> Interfaces;
  		internal Dictionary<uint, Row<ushort, uint>> ClassLayouts;
  		internal Dictionary<uint, uint> FieldLayouts;
  		internal Dictionary<uint, uint> FieldRVAs;
  		internal Dictionary<MetadataToken, uint> FieldMarshals;
  		internal Dictionary<MetadataToken, Row<ElementType, uint>> Constants;
  		internal Dictionary<uint, MetadataToken []> Overrides;
  		internal Dictionary<MetadataToken, Range> CustomAttributes;
  		internal Dictionary<MetadataToken, Range> SecurityDeclarations;
  		internal Dictionary<uint, Range> Events;
  		internal Dictionary<uint, Range> Properties;
  		internal Dictionary<uint, Row<MethodSemanticsAttributes, MetadataToken>> Semantics;
  		internal Dictionary<uint, Row<PInvokeAttributes, uint, uint>> PInvokes;
  		internal Dictionary<MetadataToken, Range> GenericParameters;
  		internal Dictionary<uint, MetadataToken []> GenericConstraints;
  
  		static Dictionary<string, Row<ElementType, bool>> primitive_value_types;
  
  		static void InitializePrimitives ()
  		{
  			primitive_value_types = new Dictionary<string, Row<ElementType, bool>> (18) {
  				{ "Void", new Row<ElementType, bool> (ElementType.Void, false) },
  				{ "Boolean", new Row<ElementType, bool> (ElementType.Boolean, true) },
  				{ "Char", new Row<ElementType, bool> (ElementType.Char, true) },
  				{ "SByte", new Row<ElementType, bool> (ElementType.I1, true) },
  				{ "Byte", new Row<ElementType, bool> (ElementType.U1, true) },
  				{ "Int16", new Row<ElementType, bool> (ElementType.I2, true) },
  				{ "UInt16", new Row<ElementType, bool> (ElementType.U2, true) },
  				{ "Int32", new Row<ElementType, bool> (ElementType.I4, true) },
  				{ "UInt32", new Row<ElementType, bool> (ElementType.U4, true) },
  				{ "Int64", new Row<ElementType, bool> (ElementType.I8, true) },
  				{ "UInt64", new Row<ElementType, bool> (ElementType.U8, true) },
  				{ "Single", new Row<ElementType, bool> (ElementType.R4, true) },
  				{ "Double", new Row<ElementType, bool> (ElementType.R8, true) },
  				{ "String", new Row<ElementType, bool> (ElementType.String, false) },
  				{ "TypedReference", new Row<ElementType, bool> (ElementType.TypedByRef, false) },
  				{ "IntPtr", new Row<ElementType, bool> (ElementType.I, true) },
  				{ "UIntPtr", new Row<ElementType, bool> (ElementType.U, true) },
  				{ "Object", new Row<ElementType, bool> (ElementType.Object, false) },
  			};
  		}
  
  		public static void TryProcessPrimitiveType (TypeReference type)
  		{
  			var scope = type.scope;
  			if (scope == null)
  				return;
  
  			if (scope.MetadataScopeType != MetadataScopeType.AssemblyNameReference)
  				return;
  
  			if (scope.Name != "mscorlib")
  				return;
  
  			if (type.Namespace != "System")
  				return;
  
  			if (primitive_value_types == null)
  				InitializePrimitives ();
  
  			Row<ElementType, bool> primitive_data;
  			if (!primitive_value_types.TryGetValue (type.Name, out primitive_data))
  				return;
  
  			type.etype = primitive_data.Col1;
  			type.IsValueType = primitive_data.Col2;
  		}
  
  		public void Clear ()
  		{
  			if (NestedTypes != null) NestedTypes.Clear ();
  			if (ReverseNestedTypes != null) ReverseNestedTypes.Clear ();
  			if (Interfaces != null) Interfaces.Clear ();
  			if (ClassLayouts != null) ClassLayouts.Clear ();
  			if (FieldLayouts != null) FieldLayouts.Clear ();
  			if (FieldRVAs != null) FieldRVAs.Clear ();
  			if (FieldMarshals != null) FieldMarshals.Clear ();
  			if (Constants != null) Constants.Clear ();
  			if (Overrides != null) Overrides.Clear ();
  			if (CustomAttributes != null) CustomAttributes.Clear ();
  			if (SecurityDeclarations != null) SecurityDeclarations.Clear ();
  			if (Events != null) Events.Clear ();
  			if (Properties != null) Properties.Clear ();
  			if (Semantics != null) Semantics.Clear ();
  			if (PInvokes != null) PInvokes.Clear ();
  			if (GenericParameters != null) GenericParameters.Clear ();
  			if (GenericConstraints != null) GenericConstraints.Clear ();
  		}
  
  		public TypeDefinition GetTypeDefinition (uint rid)
  		{
  			if (rid < 1 || rid > Types.Length)
  				return null;
  
  			return Types [rid - 1];
  		}
  
  		public void AddTypeDefinition (TypeDefinition type)
  		{
  			Types [type.token.RID - 1] = type;
  		}
  
  		public TypeReference GetTypeReference (uint rid)
  		{
  			if (rid < 1 || rid > TypeReferences.Length)
  				return null;
  
  			return TypeReferences [rid - 1];
  		}
  
  		public void AddTypeReference (TypeReference type)
  		{
  			TypeReferences [type.token.RID - 1] = type;
  		}
  
  		public FieldDefinition GetFieldDefinition (uint rid)
  		{
  			if (rid < 1 || rid > Fields.Length)
  				return null;
  
  			return Fields [rid - 1];
  		}
  
  		public void AddFieldDefinition (FieldDefinition field)
  		{
  			Fields [field.token.RID - 1] = field;
  		}
  
  		public MethodDefinition GetMethodDefinition (uint rid)
  		{
  			if (rid < 1 || rid > Methods.Length)
  				return null;
  
  			return Methods [rid - 1];
  		}
  
  		public void AddMethodDefinition (MethodDefinition method)
  		{
  			Methods [method.token.RID - 1] = method;
  		}
  
  		public MemberReference GetMemberReference (uint rid)
  		{
  
gt: 			if (rid < 1 || rid > MemberReferences.Length)