/// <summary>
 /// Visits the specified schema.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="schema">The schema.</param>
 public void Visit <T>(IValueSchema <T?> schema) where T : struct
 {
     SchemaType = schema.GetType();
     ValueType  = schema.Type;
     Hint       = GetHint(schema);
     JsonValue  = Serialize(schema);
 }
        /// <summary>
        /// Deserialize schemas and collection elements
        /// </summary>
        /// <param name="collection"></param>
        /// <returns></returns>
        public static IPropertySetCollection Deserialize(this PersistentPropertyCollection collection)
        {
            PropertySchemaSet     schemaSet = new PropertySchemaSet(new PropertySchemaFactory());
            PropertySetCollection restored  = new PropertySetCollection(schemaSet);

            //restore schemas
            foreach (PersistentPropertyElement element in collection.Elements)
            {
                PersistentSchemaElement schemaElement = collection.Schemas.First(s => s.SchemaName == element.Name);
                var valueSchema            = JsonSchemaDeserializer.Deserialize(schemaElement.SchemaType, schemaElement.SchemaBody);
                SerializationTypeHint hint = (SerializationTypeHint)schemaElement.SerializationHint;
                Func <PersistentPropertyElement, object> valueRetriever;
                if (!_serializationMap.TryGetValue(hint, out valueRetriever))
                {
                    throw new ArgumentException($"{element.Name} {hint}");
                }
                object val = valueRetriever(element);
                switch (hint)
                {
                case SerializationTypeHint.JsonString:
                    val = valueSchema.Serializer.Deserialize(val.ToString());
                    break;

                case SerializationTypeHint.BinaryObject:
                case SerializationTypeHint.Object:
                    byte[] data = (byte[])val;
                    val = valueSchema.Serializer.Deserialize(data);
                    break;
                }
                restored.Add(element.Name, val, valueSchema);
            }
            return(restored);
        }