public static Object project(Schema source, Object record, Schema target) throws SchemaProjectorException {
        checkMaybeCompatible(source, target);
        if (source.isOptional() && !target.isOptional()) {
            if (target.defaultValue() != null) {
                if (record != null) {
                    return projectRequiredSchema(source, record, target);
                } else {
                    return target.defaultValue();
                }
            } else {
                throw new SchemaProjectorException("Writer schema is optional, however, target schema does not provide a default value.");
            }
        } else {
            if (record != null) {
                return projectRequiredSchema(source, record, target);
            } else {
                return null;
            }
        }
    }
@Test
    public void testMapProjection() {
        Schema source = SchemaBuilder.map(Schema.INT32_SCHEMA, Schema.INT32_SCHEMA).optional().build();

        Schema target = SchemaBuilder.map(Schema.INT32_SCHEMA, Schema.INT32_SCHEMA).defaultValue(Collections.singletonMap(1, 2)).build();
        Object projected = SchemaProjector.project(source, Collections.singletonMap(3, 4), target);
        assertEquals(Collections.singletonMap(3, 4), projected);
        projected = SchemaProjector.project(source, null, target);
        assertEquals(Collections.singletonMap(1, 2), projected);

        Schema promotedTarget = SchemaBuilder.map(Schema.INT64_SCHEMA, Schema.FLOAT32_SCHEMA).defaultValue(
                Collections.singletonMap(3L, 4.5F)).build();
        projected = SchemaProjector.project(source, Collections.singletonMap(3, 4), promotedTarget);
        assertEquals(Collections.singletonMap(3L, 4.F), projected);
        projected = SchemaProjector.project(source, null, promotedTarget);
        assertEquals(Collections.singletonMap(3L, 4.5F), projected);

        Schema noDefaultValueTarget = SchemaBuilder.map(Schema.INT32_SCHEMA, Schema.INT32_SCHEMA).build();
        assertThrows(SchemaProjectorException.class,
            () -> SchemaProjector.project(source, null, noDefaultValueTarget),
            "Reader does not provide a default value.");

        Schema nonPromotableTarget = SchemaBuilder.map(Schema.BOOLEAN_SCHEMA, Schema.STRING_SCHEMA).build();
        assertThrows(SchemaProjectorException.class,
            () -> SchemaProjector.project(source, null, nonPromotableTarget),
            "Neither source type matches target type nor source type can be promoted to target type");
    }