protected override int ReflectionWriteMembers(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context, ClassDataContract classContract, ClassDataContract derivedMostClassContract, int childElementIndex, XmlDictionaryString[] emptyStringArray)
        {
            int memberCount = (classContract.BaseContract == null) ? 0 :
                              ReflectionWriteMembers(xmlWriter, obj, context, classContract.BaseContract, derivedMostClassContract, childElementIndex, emptyStringArray);

            childElementIndex += memberCount;

            Type classType = classContract.UnadaptedClassType;

            XmlDictionaryString[] memberNames = classContract.MemberNames;
            XmlDictionaryString   ns          = classContract.Namespace;

            context.IncrementItemCount(classContract.Members.Count);
            for (int i = 0; i < classContract.Members.Count; i++, memberCount++)
            {
                DataMember member     = classContract.Members[i];
                Type       memberType = member.MemberType;
                if (member.IsGetOnlyCollection)
                {
                    context.StoreIsGetOnlyCollection();
                }
                else
                {
                    context.ResetIsGetOnlyCollection();
                }

                bool   shouldWriteValue = true;
                object memberValue      = null;
                if (!member.EmitDefaultValue)
                {
                    memberValue = ReflectionGetMemberValue(obj, member);
                    object defaultValue = XmlFormatGeneratorStatics.GetDefaultValue(memberType);
                    if ((memberValue == null && defaultValue == null) ||
                        (memberValue != null && memberValue.Equals(defaultValue)))
                    {
                        shouldWriteValue = false;

                        if (member.IsRequired)
                        {
                            XmlObjectSerializerWriteContext.ThrowRequiredMemberMustBeEmitted(member.Name, classContract.UnderlyingType);
                        }
                    }
                }

                if (shouldWriteValue)
                {
                    bool writeXsiType = CheckIfMemberHasConflict(member, classContract, derivedMostClassContract);
                    if (memberValue == null)
                    {
                        memberValue = ReflectionGetMemberValue(obj, member);
                    }
                    PrimitiveDataContract primitiveContract = member.MemberPrimitiveContract;

                    if (writeXsiType || !ReflectionTryWritePrimitive(xmlWriter, context, memberType, memberValue, memberNames[i + childElementIndex] /*name*/, ns, primitiveContract))
                    {
                        ReflectionWriteStartElement(xmlWriter, memberType, ns, ns.Value, member.Name, 0);
                        if (classContract.ChildElementNamespaces[i + childElementIndex] != null)
                        {
                            var nsChildElement = classContract.ChildElementNamespaces[i + childElementIndex];
                            xmlWriter.WriteNamespaceDecl(nsChildElement);
                        }
                        ReflectionWriteValue(xmlWriter, context, memberType, memberValue, writeXsiType, primitiveContractForParamType: null);
                        ReflectionWriteEndElement(xmlWriter);
                    }

                    if (classContract.HasExtensionData)
                    {
                        context.WriteExtensionData(xmlWriter, ((IExtensibleDataObject)obj).ExtensionData, memberCount);
                    }
                }
            }

            return(memberCount);
        }
        public void ReflectionWriteCollection(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context, CollectionDataContract collectionDataContract)
        {
            XmlDictionaryString ns       = collectionDataContract.Namespace;
            XmlDictionaryString itemName = collectionDataContract.CollectionItemName;

            if (collectionDataContract.ChildElementNamespace != null)
            {
                xmlWriter.WriteNamespaceDecl(collectionDataContract.ChildElementNamespace);
            }

            if (collectionDataContract.Kind == CollectionKind.Array)
            {
                context.IncrementArrayCount(xmlWriter, (Array)obj);
                Type itemType = collectionDataContract.ItemType;
                if (!ReflectionTryWritePrimitiveArray(xmlWriter, obj, collectionDataContract.UnderlyingType, itemType, itemName, ns))
                {
                    Array array = (Array)obj;
                    PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(itemType);
                    for (int i = 0; i < array.Length; ++i)
                    {
                        _reflectionClassWriter.ReflectionWriteStartElement(xmlWriter, itemType, ns, ns.Value, itemName.Value, 0);
                        _reflectionClassWriter.ReflectionWriteValue(xmlWriter, context, itemType, array.GetValue(i), false, primitiveContract);
                        _reflectionClassWriter.ReflectionWriteEndElement(xmlWriter);
                    }
                }
            }
            else
            {
                collectionDataContract.IncrementCollectionCount(xmlWriter, obj, context);

                IEnumerator           enumerator = collectionDataContract.GetEnumeratorForCollection(obj);
                PrimitiveDataContract primitiveContractForType = PrimitiveDataContract.GetPrimitiveDataContract(collectionDataContract.UnderlyingType);

                if (primitiveContractForType != null && primitiveContractForType.UnderlyingType != Globals.TypeOfObject)
                {
                    while (enumerator.MoveNext())
                    {
                        object current = enumerator.Current;
                        context.IncrementItemCount(1);
                        primitiveContractForType.WriteXmlElement(xmlWriter, current, context, itemName, ns);
                    }
                }
                else
                {
                    Type elementType  = collectionDataContract.GetCollectionElementType();
                    bool isDictionary = collectionDataContract.Kind == CollectionKind.Dictionary || collectionDataContract.Kind == CollectionKind.GenericDictionary;
                    while (enumerator.MoveNext())
                    {
                        object current = enumerator.Current;
                        context.IncrementItemCount(1);
                        _reflectionClassWriter.ReflectionWriteStartElement(xmlWriter, elementType, ns, ns.Value, itemName.Value, 0);
                        if (isDictionary)
                        {
                            collectionDataContract.ItemContract.WriteXmlValue(xmlWriter, current, context);
                        }
                        else
                        {
                            _reflectionClassWriter.ReflectionWriteValue(xmlWriter, context, elementType, current, false, primitiveContractForParamType: null);
                        }

                        _reflectionClassWriter.ReflectionWriteEndElement(xmlWriter);
                    }
                }
            }
        }
        int WriteMembers(ClassDataContract classContract, ExtensionDataObject extensionData, ClassDataContract derivedMostClassContract)
        {
            int memberCount = (classContract.BaseContract == null) ? 0 : WriteMembers(classContract.BaseContract, extensionData, derivedMostClassContract);

            XmlDictionaryString ns =
                (contractNamespaces == null) ? dataContract.Namespace :
                contractNamespaces [typeIndex - 1];

            ctx.IncrementItemCount(classContract.Members.Count);

            for (int i = 0; i < classContract.Members.Count; i++, memberCount++)
            {
                DataMember member      = classContract.Members[i];
                Type       memberType  = member.MemberType;
                object     memberValue = null;
                if (member.IsGetOnlyCollection)
                {
                    ctx.StoreIsGetOnlyCollection();
                }
                bool doWrite = true, hasMemberValue = false;
                if (!member.EmitDefaultValue)
                {
                    hasMemberValue = true;
                    memberValue    = LoadMemberValue(member);
                    doWrite        = !IsDefaultValue(memberType, memberValue);
                }

                if (doWrite)
                {
                    bool writeXsiType = CheckIfMemberHasConflict(member, classContract, derivedMostClassContract);
                    if (writeXsiType || !TryWritePrimitive(memberType, hasMemberValue ? () => memberValue : (Func <object>)null, member.MemberInfo, null /*arrayItemIndex*/, ns, null /*nameLocal*/, i + childElementIndex))
                    {
                        WriteStartElement(memberType, classContract.Namespace, ns, null /*nameLocal*/, i + childElementIndex);
                        if (classContract.ChildElementNamespaces [i + childElementIndex] != null)
                        {
                            writer.WriteNamespaceDecl(childElementNamespaces [i + childElementIndex]);
                        }
                        if (memberValue == null)
                        {
                            memberValue = LoadMemberValue(member);
                        }
                        WriteValue(memberType, memberValue, writeXsiType);
                        WriteEndElement();
                    }

                    if (classContract.HasExtensionData)
                    {
                        ctx.WriteExtensionData(writer, extensionData, memberCount);
                    }
                }
                else if (!member.EmitDefaultValue)
                {
                    if (member.IsRequired)
                    {
                        XmlObjectSerializerWriteContext.ThrowRequiredMemberMustBeEmitted(member.Name, classContract.UnderlyingType);
                    }
                }
            }

            typeIndex++;
            childElementIndex += classContract.Members.Count;
            return(memberCount);
        }