/// <summary>
        /// Populates an array value.
        /// </summary>
        /// <param name="state">The loader state.</param>
        /// <param name="member">The member to populate.</param>
        /// <param name="element">The element that defines the member's value.</param>
        private void PopulateArray(ObjectLoaderState state, ObjectLoaderMember member, XElement element)
        {
            // Make sure that the array is properly defined.
            var itemsRoot = element.Element("Items");

            if (itemsRoot != null && itemsRoot.Elements().Where(x => x.Name != "Item").Any())
            {
                throw new InvalidOperationException(CoreStrings.NonItemElementsInArrayDef);
            }

            // Create the array.
            var items            = (itemsRoot == null) ? new List <XElement>() : itemsRoot.Elements("Item").ToList();
            var arrayElementType = member.MemberType.GetElementType();
            var array            = Array.CreateInstance(arrayElementType, items.Count);

            member.SetValueFromData(array, element);

            // Populate the array's items.
            for (int i = 0; i < items.Count; i++)
            {
                var value = default(Object);
                var type  = GetTypeFromElement(state, arrayElementType, items[i]);
                if (items[i].Elements().Any())
                {
                    value = CreateObject(state, type, null, GetSpecifiedConstructorArguments(items[i]));
                    value = PopulateObjectFromElements(state, value, items[i]);
                }
                else
                {
                    value = ObjectResolver.FromString(items[i].Value, type);
                }
                array.SetValue(value, i);
            }
        }
        /// <summary>
        /// Populates an enumerable value.
        /// </summary>
        /// <param name="state">The loader state.</param>
        /// <param name="member">The member to populate.</param>
        /// <param name="element">The element that defines the member's value.</param>
        private void PopulateEnumerable(ObjectLoaderState state, ObjectLoaderMember member, XElement element)
        {
            var listElemType = GetEnumerableElementType(element.Name.LocalName, member.MemberType);
            var listType     = typeof(List <>).MakeGenericType(listElemType);
            var listInstance = Activator.CreateInstance(listType);

            PopulateListItems(state, listInstance, listElemType, element);

            member.SetValueFromData(listInstance, element);
        }
        /// <summary>
        /// Populates a list value.
        /// </summary>
        /// <param name="state">The loader state.</param>
        /// <param name="member">The member to populate.</param>
        /// <param name="element">The element that defines the member's value.</param>
        private void PopulateList(ObjectLoaderState state, ObjectLoaderMember member, XElement element)
        {
            // Create the list.
            var listImplType = GetListImplementationType(member.MemberType);
            var listElemType = GetListElementType(element.Name.LocalName, listImplType);
            var list         = Activator.CreateInstance(listImplType);

            // Populate the list's members.
            if (!member.IsIndexer)
            {
                PopulateObjectFromAttributes(state, list, element);
            }
            PopulateObjectFromElements(state, list, element, x => x.Name != "Items");
            PopulateListItems(state, list, listElemType, element);

            // Set the list on the object.
            member.SetValueFromData(list, element);
        }
        /// <summary>
        /// Populates an object from the attributes defined on the specified data element.
        /// </summary>
        /// <param name="state">The loader state.</param>
        /// <param name="objectInstance">The object instance.</param>
        /// <param name="objectElement">The object element.</param>
        /// <returns>The object instance.</returns>
        private Object PopulateObjectFromAttributes(ObjectLoaderState state, Object objectInstance, XElement objectElement)
        {
            foreach (var attr in objectElement.Attributes())
            {
                if (IsReservedKeyword(attr.Name.LocalName))
                {
                    continue;
                }

                var attrMember = ObjectLoaderMember.Find(objectInstance, attr.Name.LocalName, state.IgnoreMissingMembers);
                if (attrMember != null)
                {
                    if (state.Resolver != null && state.Resolver(objectInstance, attr.Name.LocalName, attr.Value))
                    {
                        continue;
                    }

                    var attrValue = ObjectResolver.FromString(attr.Value, attrMember.MemberType);
                    attrMember.SetValue(attrValue, null);
                }
            }

            return(objectInstance);
        }
        /// <summary>
        /// Populates an object member from the specified data element.
        /// </summary>
        /// <param name="state">The loader state.</param>
        /// <param name="objectInstance">The object instance.</param>
        /// <param name="memberElement">The element that defines the member.</param>
        /// <param name="skipReservedKeywords">A value indicating whether to skip elements with the same names as reserved keywords.</param>
        /// <returns>The object instance.</returns>
        private Object PopulateMemberFromElement(ObjectLoaderState state, Object objectInstance, XElement memberElement, Boolean skipReservedKeywords = true)
        {
            if (IsReservedKeyword(memberElement.Name.LocalName))
            {
                if (skipReservedKeywords || IsForbiddenKeyword(memberElement.Name.LocalName))
                {
                    return(objectInstance);
                }
            }

            if (state.Resolver != null && state.Resolver(objectInstance, memberElement.Name.LocalName, memberElement.Value))
            {
                return(objectInstance);
            }

            var member = ObjectLoaderMember.Find(objectInstance, memberElement.Name.LocalName, state.IgnoreMissingMembers);

            if (member == null)
            {
                return(objectInstance);
            }

            // Handle array values.
            if (member.MemberType.IsArray)
            {
                PopulateArray(state, member, memberElement);
                return(objectInstance);
            }

            // Handle list values.
            if (IsListType(member.MemberType))
            {
                PopulateList(state, member, memberElement);
                return(objectInstance);
            }

            // Handle generic enumerables.
            if (IsEnumerableType(member.MemberType))
            {
                PopulateEnumerable(state, member, memberElement);
                return(objectInstance);
            }

            // Handle complex and simple objects.
            if (memberElement.Elements().Any())
            {
                var complexType      = GetTypeFromElement(state, member.MemberType, memberElement);
                var complexTypeValue = member.GetValueFromData(memberElement);
                if (complexTypeValue == null)
                {
                    complexTypeValue = CreateObject(state, complexType, null, GetSpecifiedConstructorArguments(memberElement));
                    if (!complexType.IsValueType)
                    {
                        member.SetValueFromData(complexTypeValue, memberElement);
                    }
                }

                if (!member.IsIndexer)
                {
                    complexTypeValue = PopulateObjectFromAttributes(state, complexTypeValue, memberElement);
                }
                complexTypeValue = PopulateObjectFromElements(state, complexTypeValue, memberElement);

                if (complexType.IsValueType)
                {
                    member.SetValueFromData(complexTypeValue, memberElement);
                }
            }
            else
            {
                if (String.IsNullOrEmpty(memberElement.Value))
                {
                    return(objectInstance);
                }

                var memberValue = ParseValue(memberElement.Value, member.MemberType, state.Culture);
                member.SetValueFromData(memberValue, memberElement);
            }

            return(objectInstance);
        }