public static <T> JSONSchema<T> of(SchemaDefinition<T> schemaDefinition) {
        SchemaReader<T> reader = schemaDefinition.getSchemaReaderOpt()
                .orElseGet(() -> new JacksonJsonReader<>(jsonMapper(), schemaDefinition.getPojo()));
        SchemaWriter<T> writer = schemaDefinition.getSchemaWriterOpt()
                .orElseGet(() -> new JacksonJsonWriter<>(jsonMapper()));
        return new JSONSchema<>(parseSchemaInfo(schemaDefinition, SchemaType.JSON), schemaDefinition.getPojo(),
                reader, writer);
    }
@Test
    public void testNotAllowNullCorrectPolymorphism() {
        Bar bar = new Bar();
        bar.setField1(true);

        DerivedFoo derivedFoo = new DerivedFoo();
        derivedFoo.setField1("foo1");
        derivedFoo.setField2("bar2");
        derivedFoo.setField3(4);
        derivedFoo.setField4(bar);
        derivedFoo.setField5("derived1");
        derivedFoo.setField6(2);

        Foo foo = new Foo();
        foo.setField1("foo1");
        foo.setField2("bar2");
        foo.setField3(4);
        foo.setField4(bar);

        SchemaTestUtils.DerivedDerivedFoo derivedDerivedFoo = new SchemaTestUtils.DerivedDerivedFoo();
        derivedDerivedFoo.setField1("foo1");
        derivedDerivedFoo.setField2("bar2");
        derivedDerivedFoo.setField3(4);
        derivedDerivedFoo.setField4(bar);
        derivedDerivedFoo.setField5("derived1");
        derivedDerivedFoo.setField6(2);
        derivedDerivedFoo.setFoo2(foo);
        derivedDerivedFoo.setDerivedFoo(derivedFoo);

        // schema for base class
        JSONSchema<Foo> baseJsonSchema = JSONSchema.of(SchemaDefinition.<Foo>builder().withPojo(Foo.class).build());
        Assert.assertEquals(baseJsonSchema.decode(baseJsonSchema.encode(foo)), foo);
        Assert.assertEquals(baseJsonSchema.decode(baseJsonSchema.encode(derivedFoo)), foo);
        Assert.assertEquals(baseJsonSchema.decode(baseJsonSchema.encode(derivedDerivedFoo)), foo);

        // schema for derived class
        JSONSchema<DerivedFoo> derivedJsonSchema = JSONSchema.of(SchemaDefinition.<DerivedFoo>builder().withPojo(DerivedFoo.class).build());
        Assert.assertEquals(derivedJsonSchema.decode(derivedJsonSchema.encode(derivedFoo)), derivedFoo);
        Assert.assertEquals(derivedJsonSchema.decode(derivedJsonSchema.encode(derivedDerivedFoo)), derivedFoo);

        //schema for derived derived class
        JSONSchema<SchemaTestUtils.DerivedDerivedFoo> derivedDerivedJsonSchema
                = JSONSchema.of(SchemaDefinition.<SchemaTestUtils.DerivedDerivedFoo>builder().withPojo(SchemaTestUtils.DerivedDerivedFoo.class).build());
        Assert.assertEquals(derivedDerivedJsonSchema.decode(derivedDerivedJsonSchema.encode(derivedDerivedFoo)), derivedDerivedFoo);
    }