private object ConvertToObject(IDictionary <string, object> dict, Type type)
        {
            if (_typeResolver != null)
            {
                if (dict.Keys.Contains(SerializedTypeNameKey))
                {
                    // already Evaluated
                    type = _typeResolver.ResolveType((string)dict[SerializedTypeNameKey]);
                }
            }

            var isDictionaryWithGuidKey = false;

            if (type.IsGenericType)
            {
                var genericTypeDefinition = type.GetGenericTypeDefinition();
                if (genericTypeDefinition.IsAssignableFrom(typeof(IDictionary <,>)) ||
                    genericTypeDefinition.GetInterfaces().Any(i => i == typeof(IDictionary)))
                {
                    var arguments = type.GetGenericArguments();
                    if (arguments == null || arguments.Length != 2 ||
                        (arguments[0] != typeof(object) && arguments[0] != typeof(string) &&
                         arguments[0] != typeof(Guid)))
                    {
                        throw new InvalidOperationException(
                                  "Type '" + type +
                                  "' is not not supported for serialization/deserialization of a dictionary, keys must be strings, guids or objects.");
                    }
                    if (type.IsAbstract)
                    {
                        var dictType = typeof(Dictionary <,>);
                        type = dictType.MakeGenericType(arguments[0], arguments[1]);
                    }

                    isDictionaryWithGuidKey = arguments[0] == typeof(Guid);
                }
            }
            else if (type.IsAssignableFrom(typeof(IDictionary)))
            {
                type = typeof(Dictionary <string, object>);
            }

            var target = Activator.CreateInstance(type, true);

            foreach (KeyValuePair <string, object> entry in dict)
            {
                var value = entry.Value;
                if (target is IDictionary)
                {
                    var valueType = ReflectionUtils.GetTypedDictionaryValueType(type);
                    if (value != null && valueType == typeof(Object))
                    {
                        valueType = value.GetType();
                    }

                    if (isDictionaryWithGuidKey)
                    {
                        ((IDictionary)target).Add(new Guid(entry.Key), ConvertToType(valueType, value));
                    }
                    else
                    {
                        ((IDictionary)target).Add(entry.Key, ConvertToType(valueType, value));
                    }
                    continue;
                }
                var memberCollection = type.GetMember(entry.Key,
                                                      BindingFlags.Public | BindingFlags.Instance |
                                                      BindingFlags.IgnoreCase);
                if (memberCollection == null || memberCollection.Length == 0)
                {
                    //must evaluate value
                    Evaluate(value);
                    continue;
                }

                var member = memberCollection[0];

                if (!ReflectionUtils.CanSetMemberValue(member))
                {
                    //must evaluate value
                    Evaluate(value);
                    continue;
                }

                var memberType = ReflectionUtils.GetMemberUnderlyingType(member);

                if (memberType.IsInterface)
                {
                    if (memberType.IsGenericType)
                    {
                        memberType = ResolveGenericInterfaceToType(memberType);
                    }
                    else
                    {
                        memberType = ResolveInterfaceToType(memberType);
                    }

                    if (memberType == null)
                    {
                        throw new InvalidOperationException(
                                  "Unable to deserialize a member, as its type is an unknown interface.");
                    }
                }

                ReflectionUtils.SetMemberValue(member, target, ConvertToType(memberType, value));
            }

            return(target);
        }