private object ConvertValue(Type type, object value)
        {
            string stringValue = Convert.ToString(value, this.Culture);

            // check for nullable and extract underlying type
#if !WINDOWS_UWP
            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>))
#else
            if (type.GetTypeInfo().IsGenericType&& type.GetGenericTypeDefinition() == typeof(Nullable <>))
#endif
            {
                // Since the type is nullable and no value is provided return null
                if (string.IsNullOrEmpty(stringValue))
                {
                    return(null);
                }

                type = type.GetGenericArguments()[0];
            }

            if (type == typeof(object))
            {
                if (value == null)
                {
                    return(null);
                }
                type = value.GetType();
            }

#if !WINDOWS_UWP
            if (type.IsPrimitive)
            {
                return(value.ChangeType(type, this.Culture));
            }

            if (type.IsEnum)
            {
                return(type.FindEnumValue(stringValue, this.Culture));
            }
#else
            if (type.GetTypeInfo().IsPrimitive)
            {
                return(value.ChangeType(type, this.Culture));
            }

            if (type.GetTypeInfo().IsEnum)
            {
                return(type.FindEnumValue(stringValue, this.Culture));
            }
#endif

            if (type == typeof(Uri))
            {
                return(new Uri(stringValue, UriKind.RelativeOrAbsolute));
            }

            if (type == typeof(string))
            {
                return(stringValue);
            }

            if (type == typeof(DateTime)
#if !PocketPC
                || type == typeof(DateTimeOffset)
#endif
                )
            {
                DateTime dt;

                if (this.DateFormat.HasValue())
                {
                    dt = DateTime.ParseExact(stringValue, this.DateFormat, this.Culture,
                                             DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
                }
                else
                {
                    // try parsing instead
                    dt = stringValue.ParseJsonDate(this.Culture);
                }

                if (type == typeof(DateTime))
                {
                    return(dt);
                }

#if !PocketPC
                if (type == typeof(DateTimeOffset))
                {
                    return((DateTimeOffset)dt);
                }
#endif
            }
            else if (type == typeof(decimal))
            {
                if (value is double)
                {
                    return((decimal)((double)value));
                }

                if (stringValue.Contains("e"))
                {
                    return(decimal.Parse(stringValue, NumberStyles.Float, this.Culture));
                }

                return(decimal.Parse(stringValue, this.Culture));
            }
            else if (type == typeof(Guid))
            {
                return(string.IsNullOrEmpty(stringValue)
                    ? Guid.Empty
                    : new Guid(stringValue));
            }
            else if (type == typeof(TimeSpan))
            {
                TimeSpan timeSpan;

                if (TryParse.TimeSpan(stringValue, out timeSpan))
                {
                    return(timeSpan);
                }

                // This should handle ISO 8601 durations
                return(XmlConvert.ToTimeSpan(stringValue));
            }
#if !WINDOWS_UWP
            else if (type.IsGenericType)
#else
            else if (type.GetTypeInfo().IsGenericType)
#endif
            {
                Type genericTypeDef = type.GetGenericTypeDefinition();

                if (genericTypeDef == typeof(IEnumerable <>))
                {
                    Type itemType = type.GetGenericArguments()[0];
                    Type listType = typeof(List <>).MakeGenericType(itemType);
                    return(this.BuildList(listType, value));
                }

                if (genericTypeDef == typeof(List <>))
                {
                    return(this.BuildList(type, value));
                }

                if (genericTypeDef == typeof(Dictionary <,>))
                {
                    return(this.BuildDictionary(type, value));
                }

                // nested property classes
                return(this.CreateAndMap(type, value));
            }
            else if (type.IsSubclassOfRawGeneric(typeof(List <>)))
            {
                // handles classes that derive from List<T>
                return(this.BuildList(type, value));
            }
            else if (type == typeof(JsonObject))
            {
                // simplify JsonObject into a Dictionary<string, object>
                return(this.BuildDictionary(typeof(Dictionary <string, object>), value));
            }
            else
            {
                // nested property classes
                return(this.CreateAndMap(type, value));
            }

            return(null);
        }