void WriteCollection(CollectionDataContract collectionContract)
        {
            XmlDictionaryString itemNamespace = dataContract.Namespace;

            XmlDictionaryString itemName = collectionDataContract.CollectionItemName;

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

            if (collectionContract.Kind == CollectionKind.Array)
            {
                Type itemType = collectionContract.ItemType;
                int  i;

                // This check does not exist in the original dynamic code,
                // but there is no other way to check type mismatch.
                // CollectionSerialization.ArrayContract() shows that it is required.
                if (objLocal.GetType().GetElementType() != itemType)
                {
                    throw new InvalidCastException(string.Format("Cannot cast array of {0} to array of {1}", objLocal.GetType().GetElementType(), itemType));
                }

                ctx.IncrementArrayCount(writer, (Array)objLocal);

                if (!TryWritePrimitiveArray(collectionContract.UnderlyingType, itemType, () => objLocal, itemName, itemNamespace))
                {
                    var arr = (Array)objLocal;
                    var idx = new int [1];
                    for (i = 0; i < arr.Length; i++)
                    {
                        if (!TryWritePrimitive(itemType, null, null, i, itemNamespace, itemName, 0))
                        {
                            WriteStartElement(itemType, collectionContract.Namespace, itemNamespace, itemName, 0);
                            idx [0] = i;
                            var mbrVal = arr.GetValue(idx);
                            WriteValue(itemType, mbrVal, false);
                            WriteEndElement();
                        }
                    }
                }
            }
            else
            {
                // This check does not exist in the original dynamic code,
                // but there is no other way to check type mismatch.
                // CollectionSerialization.ArrayContract() shows that it is required.
                if (!collectionContract.UnderlyingType.IsAssignableFrom(objLocal.GetType()))
                {
                    throw new InvalidCastException(string.Format("Cannot cast {0} to {1}", objLocal.GetType(), collectionContract.UnderlyingType));
                }

                MethodInfo incrementCollectionCountMethod = null;
                switch (collectionContract.Kind)
                {
                case CollectionKind.Collection:
                case CollectionKind.List:
                case CollectionKind.Dictionary:
                    incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountMethod;
                    break;

                case CollectionKind.GenericCollection:
                case CollectionKind.GenericList:
                    incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(collectionContract.ItemType);
                    break;

                case CollectionKind.GenericDictionary:
                    incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(Globals.TypeOfKeyValuePair.MakeGenericType(collectionContract.ItemType.GetGenericArguments()));
                    break;
                }
                if (incrementCollectionCountMethod != null)
                {
                    incrementCollectionCountMethod.Invoke(ctx, new object [] { writer, objLocal });
                }

                bool    isDictionary = false, isGenericDictionary = false;
                Type    enumeratorType = null;
                Type [] keyValueTypes  = null;
                if (collectionContract.Kind == CollectionKind.GenericDictionary)
                {
                    isGenericDictionary = true;
                    keyValueTypes       = collectionContract.ItemType.GetGenericArguments();
                    enumeratorType      = Globals.TypeOfGenericDictionaryEnumerator.MakeGenericType(keyValueTypes);
                }
                else if (collectionContract.Kind == CollectionKind.Dictionary)
                {
                    isDictionary   = true;
                    keyValueTypes  = new Type[] { Globals.TypeOfObject, Globals.TypeOfObject };
                    enumeratorType = Globals.TypeOfDictionaryEnumerator;
                }
                else
                {
                    enumeratorType = collectionContract.GetEnumeratorMethod.ReturnType;
                }
                MethodInfo moveNextMethod   = enumeratorType.GetMethod(Globals.MoveNextMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
                MethodInfo getCurrentMethod = enumeratorType.GetMethod(Globals.GetCurrentMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
                if (moveNextMethod == null || getCurrentMethod == null)
                {
                    if (enumeratorType.IsInterface)
                    {
                        if (moveNextMethod == null)
                        {
                            moveNextMethod = XmlFormatGeneratorStatics.MoveNextMethod;
                        }
                        if (getCurrentMethod == null)
                        {
                            getCurrentMethod = XmlFormatGeneratorStatics.GetCurrentMethod;
                        }
                    }
                    else
                    {
                        Type           ienumeratorInterface = Globals.TypeOfIEnumerator;
                        CollectionKind kind = collectionContract.Kind;
                        if (kind == CollectionKind.GenericDictionary || kind == CollectionKind.GenericCollection || kind == CollectionKind.GenericEnumerable)
                        {
                            Type[] interfaceTypes = enumeratorType.GetInterfaces();
                            foreach (Type interfaceType in interfaceTypes)
                            {
                                if (interfaceType.IsGenericType &&
                                    interfaceType.GetGenericTypeDefinition() == Globals.TypeOfIEnumeratorGeneric &&
                                    interfaceType.GetGenericArguments()[0] == collectionContract.ItemType)
                                {
                                    ienumeratorInterface = interfaceType;
                                    break;
                                }
                            }
                        }
                        if (moveNextMethod == null)
                        {
                            moveNextMethod = CollectionDataContract.GetTargetMethodWithName(Globals.MoveNextMethodName, enumeratorType, ienumeratorInterface);
                        }
                        if (getCurrentMethod == null)
                        {
                            getCurrentMethod = CollectionDataContract.GetTargetMethodWithName(Globals.GetCurrentMethodName, enumeratorType, ienumeratorInterface);
                        }
                    }
                }
                Type   elementType  = getCurrentMethod.ReturnType;
                object currentValue = null;                 // of elementType

                var enumerator = (IEnumerator)collectionContract.GetEnumeratorMethod.Invoke(objLocal, new object [0]);
                if (isDictionary)
                {
                    enumerator = new CollectionDataContract.DictionaryEnumerator((IDictionaryEnumerator)enumerator);
                }
                else if (isGenericDictionary)
                {
                    Type            ctorParam    = Globals.TypeOfIEnumeratorGeneric.MakeGenericType(Globals.TypeOfKeyValuePair.MakeGenericType(keyValueTypes));
                    ConstructorInfo dictEnumCtor = enumeratorType.GetConstructor(Globals.ScanAllMembers, null, new Type[] { ctorParam }, null);
                    enumerator = (IEnumerator)Activator.CreateInstance(enumeratorType, new object [] { enumerator });
                }

                var emptyArray = new object [0];
                while (enumerator != null && enumerator.MoveNext())
                {
                    currentValue = getCurrentMethod.Invoke(enumerator, emptyArray);

                    if (incrementCollectionCountMethod == null)
                    {
                        XmlFormatGeneratorStatics.IncrementItemCountMethod.Invoke(ctx, new object [] { 1 });
                    }

                    if (!TryWritePrimitive(elementType, () => currentValue, null, null, itemNamespace, itemName, 0))
                    {
                        WriteStartElement(elementType, collectionContract.Namespace, itemNamespace, itemName, 0);
                        if (isGenericDictionary || isDictionary)
                        {
                            collectionDataContract.ItemContract.WriteXmlValue(writer, currentValue, ctx);
                        }
                        else
                        {
                            WriteValue(elementType, currentValue, false);
                        }
                        WriteEndElement();
                    }
                }
            }
        }
		void WriteCollection(CollectionDataContract collectionContract)
		{
			XmlDictionaryString itemNamespace = dataContract.Namespace;

			XmlDictionaryString itemName = collectionDataContract.CollectionItemName;

			if (collectionContract.ChildElementNamespace != null)
				writer.WriteNamespaceDecl (collectionDataContract.ChildElementNamespace);

			if (collectionContract.Kind == CollectionKind.Array)
			{
				Type itemType = collectionContract.ItemType;
				int i;

				// This check does not exist in the original dynamic code,
				// but there is no other way to check type mismatch.
				// CollectionSerialization.ArrayContract() shows that it is required.
				if (objLocal.GetType ().GetElementType () != itemType)
					throw new InvalidCastException (string.Format ("Cannot cast array of {0} to array of {1}", objLocal.GetType ().GetElementType (), itemType));

				ctx.IncrementArrayCount (writer, (Array) objLocal);

				if (!TryWritePrimitiveArray(collectionContract.UnderlyingType, itemType, () => objLocal, itemName, itemNamespace))
				{
					var arr = (Array) objLocal;
					var idx = new int [1];
					for (i = 0; i < arr.Length; i++) {
						if (!TryWritePrimitive(itemType, null, null, i, itemNamespace, itemName, 0)) {
							WriteStartElement (itemType, collectionContract.Namespace, itemNamespace, itemName, 0);
							idx [0] = i;
							var mbrVal = arr.GetValue (idx);
							WriteValue (itemType, mbrVal, false);
							WriteEndElement ();
						}
					}
				}
			}
			else
			{
				// This check does not exist in the original dynamic code,
				// but there is no other way to check type mismatch.
				// CollectionSerialization.ArrayContract() shows that it is required.
				if (!collectionContract.UnderlyingType.IsAssignableFrom (objLocal.GetType ()))
					throw new InvalidCastException (string.Format ("Cannot cast {0} to {1}", objLocal.GetType (), collectionContract.UnderlyingType));
				
				MethodInfo incrementCollectionCountMethod = null;
				switch (collectionContract.Kind)
				{
				case CollectionKind.Collection:
				case CollectionKind.List:
				case CollectionKind.Dictionary:
					incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountMethod;
					break;
				case CollectionKind.GenericCollection:
				case CollectionKind.GenericList:
					incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(collectionContract.ItemType);
					break;
				case CollectionKind.GenericDictionary:
					incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(Globals.TypeOfKeyValuePair.MakeGenericType(collectionContract.ItemType.GetGenericArguments()));
					break;
				}
				if (incrementCollectionCountMethod != null)
					incrementCollectionCountMethod.Invoke (ctx, new object [] {writer, objLocal});

				bool isDictionary = false, isGenericDictionary = false;
				Type enumeratorType = null;
				Type [] keyValueTypes = null;
				if (collectionContract.Kind == CollectionKind.GenericDictionary)
				{
					isGenericDictionary = true;
					keyValueTypes = collectionContract.ItemType.GetGenericArguments ();
					enumeratorType = Globals.TypeOfGenericDictionaryEnumerator.MakeGenericType (keyValueTypes);
				}
				else if (collectionContract.Kind == CollectionKind.Dictionary)
				{
					isDictionary = true;
					keyValueTypes = new Type[] { Globals.TypeOfObject, Globals.TypeOfObject };
					enumeratorType = Globals.TypeOfDictionaryEnumerator;
				}
				else
				{
					enumeratorType = collectionContract.GetEnumeratorMethod.ReturnType;
				}
				MethodInfo moveNextMethod = enumeratorType.GetMethod (Globals.MoveNextMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
				MethodInfo getCurrentMethod = enumeratorType.GetMethod (Globals.GetCurrentMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
				if (moveNextMethod == null || getCurrentMethod == null)
				{
					if (enumeratorType.IsInterface)
					{
						if (moveNextMethod == null)
							moveNextMethod = XmlFormatGeneratorStatics.MoveNextMethod;
						if (getCurrentMethod == null)
							getCurrentMethod = XmlFormatGeneratorStatics.GetCurrentMethod;
					}
					else
					{
						Type ienumeratorInterface = Globals.TypeOfIEnumerator;
						CollectionKind kind = collectionContract.Kind;
						if (kind == CollectionKind.GenericDictionary || kind == CollectionKind.GenericCollection || kind == CollectionKind.GenericEnumerable)
						{
							Type[] interfaceTypes = enumeratorType.GetInterfaces();
							foreach (Type interfaceType in interfaceTypes)
							{
								if (interfaceType.IsGenericType
									&& interfaceType.GetGenericTypeDefinition() == Globals.TypeOfIEnumeratorGeneric
									&& interfaceType.GetGenericArguments()[0] == collectionContract.ItemType)
								{
									ienumeratorInterface = interfaceType;
									break;
								}
							}
						}
						if (moveNextMethod == null)
							moveNextMethod = CollectionDataContract.GetTargetMethodWithName(Globals.MoveNextMethodName, enumeratorType, ienumeratorInterface);
						if (getCurrentMethod == null)
							getCurrentMethod = CollectionDataContract.GetTargetMethodWithName(Globals.GetCurrentMethodName, enumeratorType, ienumeratorInterface);
					}
				}
				Type elementType = getCurrentMethod.ReturnType;
				object currentValue = null; // of elementType

				var enumerator = (IEnumerator) collectionContract.GetEnumeratorMethod.Invoke (objLocal, new object [0]);
				if (isDictionary)
				{
					enumerator = new CollectionDataContract.DictionaryEnumerator ((IDictionaryEnumerator) enumerator);
				}
				else if (isGenericDictionary)
				{
					Type ctorParam = Globals.TypeOfIEnumeratorGeneric.MakeGenericType(Globals.TypeOfKeyValuePair.MakeGenericType(keyValueTypes));
					ConstructorInfo dictEnumCtor = enumeratorType.GetConstructor(Globals.ScanAllMembers, null, new Type[] { ctorParam }, null);
					enumerator = (IEnumerator) Activator.CreateInstance (enumeratorType, new object [] {enumerator});
				}

				var emptyArray = new object [0];
				while (enumerator != null && enumerator.MoveNext ()) {
					currentValue = getCurrentMethod.Invoke (enumerator, emptyArray);

					if (incrementCollectionCountMethod == null)
						XmlFormatGeneratorStatics.IncrementItemCountMethod.Invoke (ctx, new object [] {1});

					if (!TryWritePrimitive (elementType, () => currentValue, null, null, itemNamespace, itemName, 0))
					{
						WriteStartElement (elementType, collectionContract.Namespace, itemNamespace, itemName, 0);
						if (isGenericDictionary || isDictionary)
							collectionDataContract.ItemContract.WriteXmlValue (writer, currentValue, ctx);
						else
							WriteValue (elementType, currentValue, false);
						WriteEndElement();
					}
				}
			}
		}