/// <summary>
		/// Create data in the CodeMappings and DecompiledMemberReferences.
		/// </summary>
		/// <param name="token">Token of the current method.</param>
		/// <param name="member">Current member (MethodDefinition, PropertyDefinition, EventDefinition).</param>
		/// <remarks>The token is used in CodeMappings; member (and its token) is used in DecompiledMemberReferences.</remarks>
		protected virtual void CreateCodeMappings(int token, MemberReference member)
		{
			this.CodeMappings.Add(token, new List<MemberMapping>());
			
			int t = member.MetadataToken.ToInt32();
			if (!this.DecompiledMemberReferences.ContainsKey(t))
				this.DecompiledMemberReferences.Add(t, member);
		}
		/// <summary>
		/// Gets the source code and type name from metadata token and offset.
		/// </summary>
		/// <param name="codeMappings">Code mappings storage.</param>
		/// <param name="token">Metadata token.</param>
		/// <param name="ilOffset">IL offset.</param>
		/// <param name="typeName">Type definition.</param>
		/// <param name="line">Line number.</param>
		/// <remarks>It is possible to exist to different types from different assemblies with the same metadata token.</remarks>
		public static bool GetInstructionByTokenAndOffset(
			this List<MemberMapping> codeMappings,
			int token,
			int ilOffset,
			out MemberReference member,
			out int line)
		{
			member = null;
			line = 0;
			
			if (codeMappings == null)
				throw new ArgumentException("CodeMappings storage must be valid!");

            var mapping = codeMappings.FirstOrDefault(m => m.MetadataToken == token);
            if (mapping == null)
                return false;

            var codeMapping = mapping.MemberCodeMappings.FirstOrDefault(
                cm => cm.ILInstructionOffset.From <= ilOffset && ilOffset <= cm.ILInstructionOffset.To - 1);
            if (codeMapping == null)
            {
                codeMapping = mapping.MemberCodeMappings.FirstOrDefault(cm => cm.ILInstructionOffset.From > ilOffset);
                if (codeMapping == null)
                {
                    codeMapping = mapping.MemberCodeMappings.LastOrDefault();
                    if (codeMapping == null)
                        return false;
                }
            }

            member = mapping.MemberReference;
            line = codeMapping.SourceCodeLine;
            return true;
        }
		/// <summary>
		/// Create code mapping for a method.
		/// </summary>
		/// <param name="method">Method to create the mapping for.</param>
		/// <param name="codeMappings">Source code mapping storage.</param>
		/// <param name="actualMemberReference">The actual member reference.</param>
		internal static MemberMapping CreateCodeMapping(
			this MethodDefinition member,
			List<MemberMapping> codeMappings,
			MemberReference actualMemberReference = null)
		{
			if (member == null || !member.HasBody)
				return null;
			
			if (codeMappings == null)
				return null;
			
			// create IL/CSharp code mappings - used in debugger
			MemberMapping currentMemberMapping = null;

            if (codeMappings.Any(map => map.MetadataToken == member.MetadataToken.ToInt32()))
            {
                currentMemberMapping = new MemberMapping()
                {
                    MetadataToken = member.MetadataToken.ToInt32(),
                    MemberCodeMappings = new List<SourceCodeMapping>(),
                    MemberReference = actualMemberReference ?? member,
                    CodeSize = member.Body.CodeSize
                };

                codeMappings.Add(currentMemberMapping);
            }
			
			return currentMemberMapping;
		}
		public void AddMemberReference (MemberReference member)
		{
			MemberReferences [member.token.RID - 1] = member;
		}
		public static TypeReference SubstituteTypeArgs(TypeReference type, MemberReference member)
		{
			if (type is TypeSpecification) {
				ArrayType arrayType = type as ArrayType;
				if (arrayType != null) {
					TypeReference elementType = SubstituteTypeArgs(arrayType.ElementType, member);
					if (elementType != arrayType.ElementType) {
						return new ArrayType(elementType, arrayType.Dimensions);
					} else {
						return type;
					}
				}
				ByReferenceType refType = type as ByReferenceType;
				if (refType != null) {
					TypeReference elementType = SubstituteTypeArgs(refType.ElementType, member);
					return elementType != refType.ElementType ? new ByReferenceType(elementType) : type;
				}
				GenericInstanceType giType = type as GenericInstanceType;
				if (giType != null) {
					GenericInstanceType newType = new GenericInstanceType(giType.ElementType);
					bool isChanged = false;
					for (int i = 0; i < giType.GenericArguments.Count; i++) {
						newType.GenericArguments.Add(SubstituteTypeArgs(giType.GenericArguments[i], member));
						isChanged |= newType.GenericArguments[i] != giType.GenericArguments[i];
					}
					return isChanged ? newType : type;
				}
				OptionalModifierType optmodType = type as OptionalModifierType;
				if (optmodType != null) {
					TypeReference elementType = SubstituteTypeArgs(optmodType.ElementType, member);
					return elementType != optmodType.ElementType ? new OptionalModifierType(optmodType.ModifierType, elementType) : type;
				}
				RequiredModifierType reqmodType = type as RequiredModifierType;
				if (reqmodType != null) {
					TypeReference elementType = SubstituteTypeArgs(reqmodType.ElementType, member);
					return elementType != reqmodType.ElementType ? new RequiredModifierType(reqmodType.ModifierType, elementType) : type;
				}
				PointerType ptrType = type as PointerType;
				if (ptrType != null) {
					TypeReference elementType = SubstituteTypeArgs(ptrType.ElementType, member);
					return elementType != ptrType.ElementType ? new PointerType(elementType) : type;
				}
			}
			GenericParameter gp = type as GenericParameter;
			if (gp != null) {
				if (gp.Owner.GenericParameterType == GenericParameterType.Method) {
					return ((GenericInstanceMethod)member).GenericArguments[gp.Position];
				} else {
					if (member.DeclaringType is ArrayType) {
						return ((ArrayType)member.DeclaringType).ElementType;
					} else {
						return ((GenericInstanceType)member.DeclaringType).GenericArguments[gp.Position];
					}
				}
			}
			return type;
		}
		public ResolutionException (MemberReference member)
			: base ("Failed to resolve " + member.FullName)
		{
			this.member = member;
		}