private static void ReadClassDataContractMembers(DataContractJsonSerializer serializer, ClassDataContract dataContract, Dictionary <string, object> deserialzedValue, object newInstance, XmlObjectSerializerReadContextComplexJson context)
        {
            if (dataContract.BaseContract != null)
            {
                ReadClassDataContractMembers(serializer, dataContract.BaseContract, deserialzedValue, newInstance, context);
            }
            for (int i = 0; i < dataContract.Members.Count; i++)
            {
                DataMember member = dataContract.Members[i];
                object     currentMemberValue;
                if (deserialzedValue.TryGetValue(XmlConvert.DecodeName(dataContract.Members[i].Name), out currentMemberValue) ||
                    dataContract.IsKeyValuePairAdapter && deserialzedValue.TryGetValue(XmlConvert.DecodeName(dataContract.Members[i].Name.ToLowerInvariant()), out currentMemberValue))
                {
                    if (member.MemberType.GetTypeInfo().IsPrimitive || currentMemberValue == null)
                    {
                        SetMemberValue(newInstance, serializer.ConvertObjectToDataContract(member.MemberTypeContract, currentMemberValue, context), dataContract.Members[i].MemberInfo, dataContract.UnderlyingType);
                    }
                    else
                    {
                        context.PushKnownTypes(dataContract);
                        object subMemberValue = serializer.ConvertObjectToDataContract(member.MemberTypeContract, currentMemberValue, context);
                        Type   declaredType   = (member.MemberType.GetTypeInfo().IsGenericType&& member.MemberType.GetGenericTypeDefinition() == Globals.TypeOfNullable)
                            ? Nullable.GetUnderlyingType(member.MemberType)
                            : member.MemberType;

                        if (!(declaredType == Globals.TypeOfObject && subMemberValue.GetType() == Globals.TypeOfObjectArray) && declaredType != subMemberValue.GetType())
                        {
                            DataContract memberValueContract = DataContract.GetDataContract(subMemberValue.GetType());
                            context.CheckIfTypeNeedsVerifcation(member.MemberTypeContract, memberValueContract);
                        }

                        if (member.IsGetOnlyCollection)
                        {
                            PopulateReadOnlyCollection(newInstance, member, (IEnumerable)subMemberValue);
                        }
                        else
                        {
                            SetMemberValue(newInstance, subMemberValue, dataContract.Members[i].MemberInfo, dataContract.UnderlyingType);
                        }
                        context.PopKnownTypes(dataContract);
                    }
                }
                else if (member.IsRequired)
                {
                    XmlObjectSerializerWriteContext.ThrowRequiredMemberMustBeEmitted(dataContract.MemberNames[i].Value, dataContract.UnderlyingType);
                }
            }
        }
        private static void ReadClassDataContractMembers(DataContractJsonSerializer serializer, ClassDataContract dataContract, Dictionary<string, object> deserialzedValue, object newInstance, XmlObjectSerializerReadContextComplexJson context)
        {
            if (dataContract.BaseContract != null)
            {
                ReadClassDataContractMembers(serializer, dataContract.BaseContract, deserialzedValue, newInstance, context);
            }
            for (int i = 0; i < dataContract.Members.Count; i++)
            {
                DataMember member = dataContract.Members[i];
                object currentMemberValue;
                if (deserialzedValue.TryGetValue(XmlConvert.DecodeName(dataContract.Members[i].Name), out currentMemberValue) ||
                    dataContract.IsKeyValuePairAdapter && deserialzedValue.TryGetValue(XmlConvert.DecodeName(dataContract.Members[i].Name.ToLowerInvariant()), out currentMemberValue))
                {
                    if (member.MemberType.GetTypeInfo().IsPrimitive || currentMemberValue == null)
                    {
                        SetMemberValue(newInstance, serializer.ConvertObjectToDataContract(member.MemberTypeContract, currentMemberValue, context), dataContract.Members[i].MemberInfo, dataContract.UnderlyingType);
                    }
                    else
                    {
                        context.PushKnownTypes(dataContract);
                        object subMemberValue = serializer.ConvertObjectToDataContract(member.MemberTypeContract, currentMemberValue, context);
                        Type declaredType = (member.MemberType.GetTypeInfo().IsGenericType && member.MemberType.GetGenericTypeDefinition() == Globals.TypeOfNullable)
                            ? Nullable.GetUnderlyingType(member.MemberType)
                            : member.MemberType;

                        if (!(declaredType == Globals.TypeOfObject && subMemberValue.GetType() == Globals.TypeOfObjectArray) && declaredType != subMemberValue.GetType())
                        {
                            DataContract memberValueContract = DataContract.GetDataContract(subMemberValue.GetType());
                            context.CheckIfTypeNeedsVerifcation(member.MemberTypeContract, memberValueContract);
                        }

                        if (member.IsGetOnlyCollection)
                        {
                            PopulateReadOnlyCollection(newInstance, member, (IEnumerable)subMemberValue);
                        }
                        else
                        {
                            SetMemberValue(newInstance, subMemberValue, dataContract.Members[i].MemberInfo, dataContract.UnderlyingType);
                        }
                        context.PopKnownTypes(dataContract);
                    }
                }
                else if (member.IsRequired)
                {
                    XmlObjectSerializerWriteContext.ThrowRequiredMemberMustBeEmitted(dataContract.MemberNames[i].Value, dataContract.UnderlyingType);
                }
            }
        }
        //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);
        }
        //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(Array.Empty<Type>()) : 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;
        }