//
        // If throwIfMissingMetadata is false, returns null rather than throwing a MissingMetadataException.
        //
        internal sealed override IList <CustomAttributeNamedArgument> GetNamedArguments(bool throwIfMissingMetadata)
        {
            LowLevelListWithIList <CustomAttributeNamedArgument> customAttributeNamedArguments = new LowLevelListWithIList <CustomAttributeNamedArgument>();

            foreach (NamedArgumentHandle namedArgumentHandle in _customAttribute.NamedArguments)
            {
                NamedArgument namedArgument             = namedArgumentHandle.GetNamedArgument(_reader);
                String        memberName                = namedArgument.Name.GetString(_reader);
                bool          isField                   = (namedArgument.Flags == NamedArgumentMemberKind.Field);
                CustomAttributeTypedArgument typedValue =
                    ParseFixedArgument(
                        _reader,
                        namedArgument.Value,
                        throwIfMissingMetadata,
                        delegate()
                {
                    // We got here because the custom attribute blob did not inclue type information. For named arguments, this is considered illegal metadata
                    // (ECMA always includes type info for named arguments.)
                    throw new BadImageFormatException();
                }
                        );
                if (typedValue.ArgumentType == null)
                {
                    Debug.Assert(!throwIfMissingMetadata);
                    return(null);
                }
                customAttributeNamedArguments.Add(ExtensibleCustomAttributeData.CreateCustomAttributeNamedArgument(this.AttributeType, memberName, isField, typedValue));
            }
            return(customAttributeNamedArguments);
        }
        public sealed override IEnumerable <CustomAttributeData> GetPsuedoCustomAttributes(MetadataReader reader, FieldHandle fieldHandle, TypeDefinitionHandle declaringTypeHandle)
        {
            TypeAttributes layoutKind = declaringTypeHandle.GetTypeDefinition(reader).Flags & TypeAttributes.LayoutMask;

            if (layoutKind == TypeAttributes.ExplicitLayout)
            {
                int offset = (int)(fieldHandle.GetField(reader).Offset);
                CustomAttributeTypedArgument offsetArgument = ExtensibleCustomAttributeData.CreateCustomAttributeTypedArgument(typeof(Int32), offset);
                yield return(ReflectionCoreExecution.ExecutionDomain.GetCustomAttributeData(typeof(FieldOffsetAttribute), new CustomAttributeTypedArgument[] { offsetArgument }, null));
            }
        }
        //
        // Wrap a custom attribute argument (or an element of an array-typed custom attribute argument) in a CustomAttributeTypeArgument structure
        // for insertion into a CustomAttributeData value.
        //
        private CustomAttributeTypedArgument WrapInCustomAttributeTypedArgument(Object value, Type argumentType)
        {
            // To support reflection domains other than the execution domain, we'll have to translate argumentType to one of the values off
            // _reflectionDomain.FoundationTypes rather than using the direct value of value.GetType(). It's unclear how to do this for
            // enum types. Cross that bridge if ever get to it.
            Debug.Assert(_reflectionDomain is ExecutionDomain);

            if (argumentType.Equals(typeof(Object)))
            {
                // If the declared attribute type is System.Object, we must report the type based on the runtime value.
                if (value == null)
                {
                    argumentType = typeof(String);  // Why is null reported as System.String? Because that's what the desktop CLR does.
                }
                else if (value is Type)
                {
                    argumentType = typeof(Type);    // value.GetType() will not actually be System.Type - rather it will be some internal implementation type. We only want to report it as System.Type.
                }
                else
                {
                    argumentType = value.GetType();
                }
            }

            Array arrayValue = value as Array;

            if (arrayValue != null)
            {
                if (!argumentType.IsArray)
                {
                    throw new BadImageFormatException();
                }
                Type reportedElementType = argumentType.GetElementType();
                LowLevelListWithIList <CustomAttributeTypedArgument> elementTypedArguments = new LowLevelListWithIList <CustomAttributeTypedArgument>();
                foreach (Object elementValue in arrayValue)
                {
                    CustomAttributeTypedArgument elementTypedArgument = WrapInCustomAttributeTypedArgument(elementValue, reportedElementType);
                    elementTypedArguments.Add(elementTypedArgument);
                }
                return(ExtensibleCustomAttributeData.CreateCustomAttributeTypedArgument(argumentType, new ReadOnlyCollection <CustomAttributeTypedArgument>(elementTypedArguments)));
            }
            else
            {
                return(ExtensibleCustomAttributeData.CreateCustomAttributeTypedArgument(argumentType, value));
            }
        }