private static void PopulateReadOnlyCollection(object instance, DataMember member, IEnumerable value)
        {
            Debug.Assert(member.IsGetOnlyCollection);

            CollectionDataContract memberContract = (CollectionDataContract)member.MemberTypeContract;
            var collection = DataContractToObjectConverter.GetMemberValue(instance, member.MemberInfo, instance.GetType());

            // Special case an array
            var array = collection as Array;

            if (array != null)
            {
                Array srcArray    = (Array)value;
                Type  elementType = srcArray.GetType().GetElementType();

                // Resize
                var resizeMethod       = typeof(Array).GetMethod("Resize", BindingFlags.Static | BindingFlags.Public);
                var properResizeMethod = resizeMethod.MakeGenericMethod(elementType);
                properResizeMethod.Invoke(null, new object[] { array, srcArray.Length });

                // Copy
                Array.Copy(srcArray, array, srcArray.Length);
                return;
            }

            // General collection
            IEnumerator enumerator  = value.GetEnumerator();
            object      currentItem = null;

            object[] currentItemArray = null;

            while (enumerator.MoveNext())
            {
                currentItem      = enumerator.Current;
                currentItemArray = new object[] { currentItem };
                // Dictionary
                if (memberContract.IsDictionary)
                {
                    Type       currentItemType = currentItem.GetType();
                    MemberInfo keyMember       = currentItemType.GetMember("Key")[0];
                    MemberInfo valueMember     = currentItemType.GetMember("Value")[0];
                    currentItemArray = new object[] { DataContractToObjectConverter.GetMemberValue(currentItem, keyMember, currentItemType), DataContractToObjectConverter.GetMemberValue(currentItem, valueMember, currentItemType) };
                }

                memberContract.AddMethod.Invoke(collection, currentItemArray);
            }
        }
        internal object ConvertDataContractToObject(object value, DataContract contract, XmlObjectSerializerWriteContextComplexJson context, bool writeServerType, RuntimeTypeHandle declaredTypeHandle)
        {
            if (context != null)
            {
                context.OnHandleReference(null /*XmlWriter*/, value, true); //  canContainReferences
            }
            try
            {
                if (contract is ObjectDataContract)
                {
                    Type valueType = value.GetType();
                    if (valueType != Globals.TypeOfObject)
                    {
                        return(ConvertDataContractToObject(value, DataContract.GetDataContract(valueType), context, true, contract.UnderlyingType.TypeHandle));
                    }
                    else
                    {
                        return(value);
                    }
                }
                else if (contract is TimeSpanDataContract)
                {
                    return(XmlConvert.ToString((TimeSpan)value));
                }
                else if (contract is QNameDataContract)
                {
                    XmlQualifiedName qname = (XmlQualifiedName)value;
                    return((qname.IsEmpty) ? string.Empty : (qname.Name + ":" + qname.Namespace));
                }
                else if (contract is PrimitiveDataContract)
                {
                    return(value);
                }
                else if (contract is CollectionDataContract)
                {
                    CollectionDataContract collectionContract = contract as CollectionDataContract;

                    switch (collectionContract.Kind)
                    {
                    case CollectionKind.GenericDictionary:
                    case CollectionKind.Dictionary:
                        return(DataContractToObjectConverter.ConvertGenericDictionaryToArray(this, (IEnumerable)value, collectionContract, context, writeServerType));

                    default:
                        return(DataContractToObjectConverter.ConvertGenericListToArray(this, (IEnumerable)value, collectionContract, context, writeServerType));
                    }
                }
                else if (contract is ClassDataContract)
                {
                    ClassDataContract classContract = contract as ClassDataContract;

                    if (Globals.TypeOfScriptObject_IsAssignableFrom(classContract.UnderlyingType))
                    {
                        return(ConvertScriptObjectToObject(value));
                    }

                    return(DataContractToObjectConverter.ConvertClassDataContractToDictionary(this, (ClassDataContract)contract, value, context, writeServerType));
                }
                else if (contract is EnumDataContract)
                {
                    if (((EnumDataContract)contract).IsULong)
                    {
                        return(Convert.ToUInt64(value, null));
                    }
                    else
                    {
                        return(Convert.ToInt64(value, null));
                    }
                }
                else if (contract is XmlDataContract)
                {
                    DataContractSerializer dataContractSerializer = new DataContractSerializer(Type.GetTypeFromHandle(declaredTypeHandle), GetKnownTypesFromContext(context, (context == null) ? null : context.SerializerKnownTypeList));
                    MemoryStream           memoryStream           = new MemoryStream();
                    dataContractSerializer.WriteObject(memoryStream, value);
                    memoryStream.Position = 0;
                    return(new StreamReader(memoryStream, Encoding.UTF8).ReadToEnd());
                }
            }
            finally
            {
                if (context != null)
                {
                    context.OnEndHandleReference(null /*XmlWriter*/, value, true); //  canContainReferences
                }
            }
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.UnknownDataContract, contract.Name)));
        }
        //Deserialize '[...]' json string. The contents of the list can also be a dictionary i.e. [{...}]. The content type is detected
        //based on the type of CollectionDataContract.ItemContract.
        public static object ConvertICollectionToCollectionDataContract(DataContractJsonSerializer serializer, CollectionDataContract contract, object deserializedValue, XmlObjectSerializerReadContextComplexJson context)
        {
            Dictionary <string, object> valueAsDictionary = deserializedValue as Dictionary <string, object>;

            //Check to see if the dictionary (if it is a dictionary)is a regular Dictionary i.e { Key="key"; Value="value} and doesnt contain the __type string
            //for ex. the dictionary { __type="XXX"; Key="key"; Value="value} needs to be parsed as ClassDataContract
            if (valueAsDictionary != null && (!valueAsDictionary.ContainsKey(JsonGlobals.KeyString) || valueAsDictionary.ContainsKey(JsonGlobals.ServerTypeString)))
            {
                //If not then its a dictionary for either of these cases
                //1. Empty object - {}
                //2. Containes the __type information
                //3. Is a DateTimeOffsetDictionary
                return(ConvertDictionary(serializer, contract, valueAsDictionary, context));
            }

            object returnValue = (contract.Constructor != null) ? contract.Constructor.Invoke(Globals.EmptyTypeArray) : null;

            bool       isCollectionDataContractDictionary = contract.IsDictionary;
            MethodInfo addMethod      = contract.AddMethod;
            bool       convertToArray = contract.Kind == CollectionKind.Array;

            if (contract.UnderlyingType.GetTypeInfo().IsInterface || returnValue == null)
            {
                switch (contract.Kind)
                {
                case CollectionKind.Collection:
                case CollectionKind.GenericCollection:
                case CollectionKind.Enumerable:
                case CollectionKind.GenericEnumerable:
                case CollectionKind.List:
                case CollectionKind.GenericList:
                case CollectionKind.Array:
                    if (contract.UnderlyingType.GetTypeInfo().IsValueType)
                    {
                        //Initialize struct
                        returnValue = XmlFormatReaderGenerator.TryGetUninitializedObjectWithFormatterServices(contract.UnderlyingType);
                    }
                    else
                    {
                        returnValue    = Activator.CreateInstance(Globals.TypeOfListGeneric.MakeGenericType(contract.ItemType));
                        convertToArray = true;
                    }
                    break;

                case CollectionKind.GenericDictionary:
                    returnValue = Activator.CreateInstance(Globals.TypeOfDictionaryGeneric.MakeGenericType(contract.ItemType.GetGenericArguments()));
                    break;

                case CollectionKind.Dictionary:
                    returnValue = Activator.CreateInstance(Globals.TypeOfDictionaryGeneric.MakeGenericType(Globals.TypeOfObject, Globals.TypeOfObject));
                    break;
                }
            }
            if (addMethod == null)
            {
                //addMethod is null for IDictionary, IList and array types.
                Type[] paramArray = (contract.ItemType.GetTypeInfo().IsGenericType&& !convertToArray) ? contract.ItemType.GetGenericArguments() : new Type[] { contract.ItemType };
                addMethod = returnValue.GetType().GetMethod(Globals.AddMethodName, paramArray);
            }

            IEnumerator enumerator  = ((ICollection)deserializedValue).GetEnumerator();
            object      currentItem = null;

            object[] currentItemArray = null;
            while (enumerator.MoveNext())
            {
                DataContract itemContract = contract.ItemContract;
                if (itemContract is ClassDataContract)
                {
                    itemContract = XmlObjectSerializerWriteContextComplexJson.GetRevisedItemContract(itemContract);
                }
                currentItem      = serializer.ConvertObjectToDataContract(itemContract, enumerator.Current, context);
                currentItemArray = new object[] { currentItem };
                if (isCollectionDataContractDictionary)
                {
                    Type       currentItemType = currentItem.GetType();
                    MemberInfo keyMember       = currentItemType.GetMember("Key")[0];
                    MemberInfo valueMember     = currentItemType.GetMember("Value")[0];
                    currentItemArray = new object[] { DataContractToObjectConverter.GetMemberValue(currentItem, keyMember, currentItemType), DataContractToObjectConverter.GetMemberValue(currentItem, valueMember, currentItemType) };
                }
                addMethod.Invoke(returnValue, currentItemArray);
            }

            return((convertToArray) ? ConvertToArray(contract.ItemType, (ICollection)returnValue) : returnValue);
        }