public void Serialize(JsonObjectValidator objectValidator,
                                      IFormatter f, JsonSchemaValidationContext c, T o)
                {
                    // Validates fields
                    var validationResults = new Dictionary <string, ValidationResult>();

                    GenericValidator <T> .ValidationResults(
                        objectValidator.Required, objectValidator.Properties,
                        c, o, validationResults);

                    // Serialize fields
                    f.BeginMap(objectValidator.Properties.Count());
                    foreach (var property in objectValidator.Properties)
                    {
                        var fieldName = property.Key;
                        var schema    = property.Value;

                        string[] deps = null;
                        objectValidator.Dependencies.TryGetValue(fieldName, out deps);

                        FieldSerializer fs;
                        if (m_serializers.TryGetValue(fieldName, out fs))
                        {
                            fs(schema, c, f, o, validationResults, deps);
                        }
                    }

                    f.EndMap();
                }
            public static void Serialize(JsonObjectValidator objectValidator,
                                         IFormatter f, JsonSchemaValidationContext c, T value)
            {
                if (s_serializer == null)
                {
                    s_serializer = new Serializer();
                }

                s_serializer.Serialize(objectValidator, f, c, value);
            }
        public static IJsonSchemaValidator Create(ValueNodeType valueType,
                                                  Type t = null,
                                                  BaseJsonSchemaAttribute a  = null,
                                                  ItemJsonSchemaAttribute ia = null)
        {
            switch (valueType)
            {
            case ValueNodeType.Integer:
            {
                var v = new JsonIntValidator();

                if (a != null)
                {
                    if (!double.IsNaN(a.Minimum))
                    {
                        v.Minimum = (int)a.Minimum;
                    }
                    if (a.ExclusiveMinimum)
                    {
                        v.ExclusiveMinimum = a.ExclusiveMinimum;
                    }
                    if (!double.IsNaN(a.Maximum))
                    {
                        v.Maximum = (int)a.Maximum;
                    }
                    if (a.ExclusiveMaximum)
                    {
                        v.ExclusiveMaximum = a.ExclusiveMaximum;
                    }
                    if (a.MultipleOf != 0)
                    {
                        v.MultipleOf = (int)a.MultipleOf;
                    }
                }

                return(v);
            }

            case ValueNodeType.Number:
            {
                var v = new JsonNumberValidator();
                if (a != null)
                {
                    if (!double.IsNaN(a.Minimum))
                    {
                        v.Minimum = (int)a.Minimum;
                    }
                    if (a.ExclusiveMinimum)
                    {
                        v.ExclusiveMinimum = a.ExclusiveMinimum;
                    }
                    if (!double.IsNaN(a.Maximum))
                    {
                        v.Maximum = (int)a.Maximum;
                    }
                    if (a.ExclusiveMaximum)
                    {
                        v.ExclusiveMaximum = a.ExclusiveMaximum;
                    }
                    if (a.MultipleOf != 0)
                    {
                        v.MultipleOf = (int)a.MultipleOf;
                    }
                }

                return(v);
            }

            case ValueNodeType.String:
            {
                var v = new JsonStringValidator();
                if (a != null)
                {
                    if (a.Pattern != null)
                    {
                        v.Pattern = new System.Text.RegularExpressions.Regex(a.Pattern);
                    }
                }
                return(v);
            }

            case ValueNodeType.Boolean:
                return(new JsonBoolValidator());

            case ValueNodeType.Array:
            {
                var v = new JsonArrayValidator();
                if (a != null)
                {
                    if (a.MinItems != 0)
                    {
                        v.MinItems = a.MinItems;
                    }
                    if (a.MaxItems != 0)
                    {
                        v.MaxItems = a.MaxItems;
                    }

                    if (t != null)
                    {
                        if (ia == null)
                        {
                            ia = new ItemJsonSchemaAttribute();
                        }

                        Type elementType = null;
                        if (t.IsArray)
                        {
                            elementType = t.GetElementType();
                        }
                        else if (t.GetIsGenericList())
                        {
                            elementType = t.GetGenericArguments().First();
                        }

                        if (elementType != null)
                        {
                            /*
                             * var sub = new JsonSchema
                             * {
                             *  SkipComparison = ia.SkipSchemaComparison,
                             *  Validator = Create(elementType, ia, null)
                             * };
                             */
                            var sub = JsonSchema.FromType(elementType, ia, null);
                            v.Items = sub;
                        }
                    }
                }

                return(v);
            }

            case ValueNodeType.Object:
            {
                if (t.GetIsGenericDictionary())
                {
                    var genericFactory =
                        typeof(JsonDictionaryValidator).GetMethod("Create",
                                                                  BindingFlags.Static | BindingFlags.Public);
                    var factory = genericFactory.MakeGenericMethod(t.GetGenericArguments()[1]);
                    var v       = factory.Invoke(null, null) as IJsonSchemaValidator;
                    return(v);
                }
                else
                {
                    var v = new JsonObjectValidator();
                    if (a != null)
                    {
                        if (a.MinProperties > 0)
                        {
                            v.MinProperties = a.MinProperties;
                        }

                        // props
                        foreach (var prop in GetProperties(t, a.ExportFlags))
                        {
                            v.Properties.Add(prop.Key, prop.Schema);
                            if (prop.Required)
                            {
                                v.Required.Add(prop.Key);
                            }
                            if (prop.Dependencies != null)
                            {
                                v.Dependencies.Add(prop.Key, prop.Dependencies);
                            }
                        }
                    }

                    if (ia != null)
                    {
                        var sub = new JsonSchema
                        {
                            SkipComparison = ia.SkipSchemaComparison,
                            Validator      = Create(typeof(object), ia, null)
                        };
                        v.AdditionalProperties = sub;
                    }

                    return(v);
                }
            }

            default:
                throw new NotImplementedException();
            }
        }