/// <summary>
        /// Enumerates EventDef tokens representing Events of the specified type.
        /// 
        /// To enumerate inherited Events, the caller must explicitly walk the inheritance chain. 
        /// </summary>
        /// <param name="typeDefinition"> A ReturnTypeDefinition representing the type whose Events are to be enumerated</param>
        /// <returns>the enumerator</returns>
        public IEnumerable<Event> EnumerateEvents(TypeDefinition typeDefinition)
        {
            // Handle of the enumeration.
            var enumHandle = 0;

            // We will read maximum 10 Events at once which will be stored in this array.
            var events = new int[10];

            // Number of read Events.
            var count = 0;
            var hresult = this.import.EnumEvents(ref enumHandle, typeDefinition.Token, events, events.Length, ref count);
            if (hresult != 0)
            {
                Marshal.ThrowExceptionForHR(hresult);
            }

            // Continue reading Events' while the Events array contains any new Event.
            while (count > 0)
            {
                for (uint eventsIndex = 0; eventsIndex < count; eventsIndex++)
                {
                    yield return this.GetEventProperties(events[eventsIndex]);
                }

                hresult = this.import.EnumEvents(ref enumHandle, typeDefinition.Token, events, events.Length, ref count);
                if (hresult != 0)
                {
                    Marshal.ThrowExceptionForHR(hresult);
                }
            }

            this.import.CloseEnum(enumHandle);
        }
        public EventMetadataICodeElementAdapter(Event @event, TypeDefinition typeDefinition, IList<TypeDescriptor> genericTypes, MetadataReader reader)
            : base(typeDefinition, genericTypes, reader)
        {
            if (@event == null)
            {
                throw new ArgumentNullException("event");
            }

            this.Event = @event;
        }
        public PropertyMetadataICodeElementAdapter(Property property, TypeDefinition typeDefinition, IList<TypeDescriptor> genericTypes, MetadataReader reader)
            : base(typeDefinition, genericTypes, reader)
        {
            if (property == null)
            {
                throw new ArgumentNullException("property");
            }

            this.Property = property;
        }
        public MethodMetadataICodeElementAdapter(Method method, TypeDefinition typeDefinition, IList<TypeDescriptor> genericTypes, MetadataReader reader)
            : base(typeDefinition, genericTypes, reader)
        {
            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            this.Method = method;
        }
        public FieldMetadataICodeElementAdapter(Field field, TypeDefinition typeDefinition, IList<TypeDescriptor> genericTypes, MetadataReader reader)
            : base(typeDefinition, genericTypes, reader)
        {
            if (field == null)
            {
                throw new ArgumentNullException("field");
            }

            this.Field = field;
        }
        public TypeDefinitionMetadataICodeElementAdapterBase(TypeDefinition typeDefinition, IList<TypeDescriptor> genericTypes, MetadataReader reader)
            : base(reader)
        {
            if (typeDefinition == null)
            {
                throw new ArgumentNullException("typeDefinition");
            }

            this.TypeDefinition = typeDefinition;
            this.GenericTypes = genericTypes;
        }
        private bool BaseIsValueTypeRecurse(TypeDefinition @base)
        {
            if (@base == null)
            {
                return false;
            }

            string fullName = @base.FullName;
            if (fullName.Equals("Platform.ValueType") || fullName.Equals("System.Enum"))
            {
                return true;
            }

            var baseReference = @base.BaseReference;
            if (baseReference != null
                && (baseReference.FullName.Equals("Platform.ValueType")
                    || baseReference.FullName.Equals("System.Enum")))
            {
                return true;
            }

            return this.BaseIsValueTypeRecurse(@base.Base);
        }
 public TypeDefinitionMetadataICodeElementAdapter(TypeDefinition typeDefinition, IList<TypeDescriptor> genericTypes, MetadataReader reader)
     : base(typeDefinition, genericTypes, reader)
 {
 }
        /// <summary>
        /// Enumerates Field tokens representing Fields of the specified type.
        /// 
        /// To enumerate inherited Fields, the caller must explicitly walk the inheritance chain. 
        /// </summary>
        /// <param name="typeDefinition"> A ReturnTypeDefinition representing the type whose Fields are to be enumerated</param>
        /// <returns>the enumerator</returns>
        public IEnumerable<Field> EnumerateFields(TypeDefinition typeDefinition)
        {
            // Handle of the enumeration.
            var enumHandle = 0;

            // We will read maximum 10 Fields at once which will be stored in this array.
            var fields = new int[10];

            // Number of read Fields.
            var count = 0;
            var hresult = this.import.EnumFields(ref enumHandle, typeDefinition.Token, fields, fields.Length, ref count);
            if (hresult != 0)
            {
                Marshal.ThrowExceptionForHR(hresult);
            }

            // Continue reading Fields' while the Fields array contains any new Field.
            while (count > 0)
            {
                for (uint fieldsIndex = 0; fieldsIndex < count; fieldsIndex++)
                {
                    yield return this.GetFieldProperties(fields[fieldsIndex]);
                }

                hresult = this.import.EnumFields(ref enumHandle, typeDefinition.Token, fields, fields.Length, ref count);
                if (hresult != 0)
                {
                    Marshal.ThrowExceptionForHR(hresult);
                }
            }

            this.import.CloseEnum(enumHandle);
        }
        /// <summary>
        /// Enumerates PropertyDef tokens representing Properties of the specified type.
        /// 
        /// To enumerate inherited Properties, the caller must explicitly walk the inheritance chain. 
        /// </summary>
        /// <param name="typeDefinition"> A ReturnTypeDefinition representing the type whose Properties are to be enumerated</param>
        /// <returns>the enumerator</returns>
        public IEnumerable<Property> EnumerateProperties(TypeDefinition typeDefinition)
        {
            // Handle of the enumeration.
            var enumHandle = 0;

            // We will read maximum 10 Properties at once which will be stored in this array.
            var properties = new int[10];

            // Number of read Properties.
            var count = 0;
            var hresult = this.import.EnumProperties(ref enumHandle, typeDefinition.Token, properties, properties.Length, ref count);
            if (hresult != 0)
            {
                Marshal.ThrowExceptionForHR(hresult);
            }

            // Continue reading Properties' while the Properties array contains any new Property.
            while (count > 0)
            {
                for (uint propertiesIndex = 0; propertiesIndex < count; propertiesIndex++)
                {
                    yield return this.GetPropertyProperties(properties[propertiesIndex]);
                }

                hresult = this.import.EnumProperties(ref enumHandle, typeDefinition.Token, properties, properties.Length, ref count);
                if (hresult != 0)
                {
                    Marshal.ThrowExceptionForHR(hresult);
                }
            }

            this.import.CloseEnum(enumHandle);
        }
        /// <summary>
        /// Enumerates MemberDef tokens representing members of the specified type.
        /// 
        /// To enumerate inherited members, the caller must explicitly walk the inheritance chain. 
        /// </summary>
        /// <param name="typeDefinition"> A ReturnTypeDefinition representing the type whose members are to be enumerated</param>
        /// <returns>the enumerator</returns>
        public IEnumerable<Member> EnumerateMembers(TypeDefinition typeDefinition)
        {
            // Handle of the enumeration.
            var enumHandle = 0;

            // We will read maximum 10 Members at once which will be stored in this array.
            var members = new int[10];

            // Number of read Members.
            var count = 0;
            var hresult = this.import.EnumMembers(ref enumHandle, typeDefinition.Token, members, members.Length, ref count);
            if (hresult != 0)
            {
                Marshal.ThrowExceptionForHR(hresult);
            }

            // Continue reading Members' while the members array contains any new Member.
            while (count > 0)
            {
                for (uint membersIndex = 0; membersIndex < count; membersIndex++)
                {
                    yield return this.GetMemberProperties(members[membersIndex]);
                }

                hresult = this.import.EnumMembers(ref enumHandle, typeDefinition.Token, members, members.Length, ref count);
                if (hresult != 0)
                {
                    Marshal.ThrowExceptionForHR(hresult);
                }
            }

            this.import.CloseEnum(enumHandle);
        }
        public TypeDefinition GetTypeDefinitionProperties(int token)
        {
            object metadataObject = null;
            if (this.metadataObjectsCache.TryGetValue(token, out metadataObject))
            {
                return (TypeDefinition)metadataObject;
            }

            // The TypeDef's name will be stored in this array. The 1024 is a "magical number", seems like a type's name can be maximum this long. The corhlpr.h also defines a suspicious constant like this: #define MAX_CLASSNAME_LENGTH 1024
            var typeName = new char[1024];

            // Number of how many characters were filled in the typeName array.
            var nameLength = 0;

            // TypeDef's flags.
            var typeDefFlags = 0;

            // If the TypeDef is a derived type then the base type's token.
            var baseTypeToken = 0;

            // Get the TypeDef's properties.
            var hresult = this.import.GetTypeDefProps(token, typeName, typeName.Length, ref nameLength, ref typeDefFlags, ref baseTypeToken);
            if (hresult != 0)
            {
                Marshal.ThrowExceptionForHR(hresult);
            }

            // supress names "" & "\0";
            if (nameLength <= 1)
            {
                // return null for this, we do not need to know about empty base
                return null;
            }

            // Get the TypeDef's name.
            var fullTypeName = new string(typeName, 0, nameLength - 1);
            var corTypeAttr = (CorTypeAttr)typeDefFlags;

            var typeDefProp = new TypeDefinition() { Token = token, FullName = fullTypeName, Type = corTypeAttr };

            this.metadataObjectsCache[token] = typeDefProp;

            if (baseTypeToken > 0)
            {
                if (baseTypeToken.Is(CorTokenType.TypeDef))
                {
                    typeDefProp.Base = this.GetTypeDefinitionProperties(baseTypeToken);
                }
                else if (baseTypeToken.Is(CorTokenType.TypeRef))
                {
                    var typeRef = this.GetTypeReferenceProperties(baseTypeToken);
                    typeDefProp.BaseReference = typeRef;
                    typeDefProp.Base = this.GetTypeDefByTypeRef(typeRef);
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            typeDefProp.Interfaces = this.EnumerateInterfaceImplementations(token).ToArray();

            return typeDefProp;
        }