private static void _DeserializationHandler(out object output, SerializedObjectNode serializedNode, Type baseType)
        {
            if (serializedNode.Value == "NULL")
            {
                output = null;
                return;
            }

            Type type = baseType;

            output = Activator.CreateInstance(type);

            //apply version updating
            Type expectedType = type;
            foreach (SerializedVersionInfo serializedVersionInfo in serializedNode.IterateVersionInfo())
            {
                Type savedType = TypeHelper.GetType(serializedVersionInfo.TypeName);
                if (savedType == expectedType || savedType == null)
                {
                    SerializedVersionInfo currentVersionInfo = SerializedVersionInfo.Create(expectedType);

                    for (int i = serializedVersionInfo.VersionNumber + 1; i <= currentVersionInfo.VersionNumber; i++)
                    {
                        MethodInfo upgradeMethodInfo = expectedType.GetMethod(string.Format("_UpgradeToVersion{0}", i),
                            BindingFlags.Static | BindingFlags.NonPublic, null, new[] {typeof(SerializedObjectNode)}, null);

                        if (upgradeMethodInfo != null)
                        {
                            foreach (SerializedObjectNode childNode in serializedNode.IterateChildren())
                            {
                                upgradeMethodInfo.Invoke(null, new object[] {childNode});
                            }
                        }
                    }
                }

                if (expectedType != null)
                    expectedType = expectedType.BaseType;
            }

            foreach (SerializedObjectNode childNode in serializedNode.IterateChildren())
            {
                FieldInfo field = TypeHelper.GetField(type, childNode.Name);
                if (field == null)
                    continue;

                Type fieldType = field.FieldType;

                object fieldObject;
                _InvokeDeserializerHandler(out fieldObject, childNode, fieldType);

                field.SetValue(output, fieldObject);
            }
        }
        private static void _DeserializationHandler(out IList output, SerializedObjectNode serializedNode, Type baseType)
        {
            Type elementType = baseType.GetElementType();
            output = Activator.CreateInstance(baseType) as IList;

            Assert.IsNotNull(output);

            foreach (SerializedObjectNode child in serializedNode.IterateChildren())
            {
                object element = FormatterServices.GetUninitializedObject(elementType);
                _InvokeDeserializerHandler(out element, child, elementType);

                output.Add(element);
            }
        }
        private static void _DeserializationHandler(out Array output, SerializedObjectNode serializedNode, Type baseType)
        {
            int length = serializedNode.GetChildCount();
            Type elementType = baseType.GetElementType();

            output = Array.CreateInstance(elementType, length);

            int i = 0;
            foreach (SerializedObjectNode serializedObjectNode in serializedNode.IterateChildren())
            {
                object element;
                _InvokeDeserializerHandler(out element, serializedObjectNode, elementType);

                output.SetValue(element, i);

                i++;
            }
        }
        private static void _DeserializationHandler(out IDictionary output, SerializedObjectNode serializedNode, Type baseType)
        {
            Type[] genericArgumenTypes = baseType.GetGenericArguments();

            output = Activator.CreateInstance(baseType) as IDictionary;

            Assert.IsNotNull(output);

            if (genericArgumenTypes.Length == 0)
                genericArgumenTypes = new[] { typeof(object), typeof(object) };

            Type keyType = genericArgumenTypes[0];
            Type valueType = genericArgumenTypes[1];

            foreach (SerializedObjectNode serializedObjectNode in serializedNode.IterateChildren())
            {
                SerializedObjectNode keyNode = serializedObjectNode["key"];
                SerializedObjectNode valueNode = serializedObjectNode["value"];

                object key;
                object value;

                _InvokeDeserializerHandler(out key, keyNode, keyType);
                _InvokeDeserializerHandler(out value, valueNode, valueType);

                output.Add(key, value);
            }
        }