static <T> T transform(Object value, Class<T> toClazz, Registry registry) {
        try {
            if (toClazz.isInstance(value)) {
                return (T) value;
            }
            else if (value instanceof BindObject) {
                T bean = newInstance(toClazz);

                for(Map.Entry<String, Object> entry : (BindObject) value) {
                    Class<?> requiredType = PropertyUtils.getPropertyType(toClazz, entry.getKey());
                    Object propValue = transform(entry.getValue(), requiredType, registry);

                    if (propValue != null) {
                        PropertyUtils.writeProperty(bean, entry.getKey(), propValue);
                    }
                }

                return bean;
            }
            else if (value instanceof Optional) {
                Optional<?> optional = (Optional) value;

                if (toClazz == Optional.class) {
                    Class<?> targetType = PropertyUtils.getGenericParamTypes(toClazz)[0];
                    return (T) optional.map(v -> transform(v, targetType, registry));
                } else {
                    return transform(optional.orElse(null), toClazz, registry);
                }
            }
            else if (value instanceof Map) {
                Map<?, ?> values = (Map) value;

                if (Map.class.isAssignableFrom(toClazz)) {
                    Class<?> keyType = PropertyUtils.getGenericParamTypes(toClazz)[0];
                    Class<?> valueType = PropertyUtils.getGenericParamTypes(toClazz)[1];

                    values = values.entrySet().stream().map(e ->
                        entry(transform(e.getKey(), keyType, registry),
                              transform(e.getValue(), valueType, registry))
                    ).collect(Collectors.toMap(
                            Map.Entry::getKey,
                            Map.Entry::getValue
                    ));

                    return doTransform(values, toClazz, registry);
                }
                else throw new IllegalArgumentException(
                        "INCOMPATIBLE transform: " + value.getClass().getName() + " -> " + toClazz.getName());
            }
            else if (value instanceof Collection) {
                Collection<?> values = (Collection) value;

                if (Collection.class.isAssignableFrom(toClazz) || toClazz.isArray()) {
                    Class<?> elemType = toClazz.isArray() ? toClazz.getComponentType()
                            : PropertyUtils.getGenericParamTypes(toClazz)[0];

                    values = values.stream().map(v -> transform(v, elemType, registry))
                            .collect(Collectors.<Object>toList());

                    return doTransform(values, toClazz, registry);
                }
                else throw new IllegalArgumentException(
                        "INCOMPATIBLE transform: " + value.getClass().getName() + " -> " + toClazz.getName());
            }
            else {
                return doTransform(value, toClazz, registry);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
static < T > T transform ( Object value , Class < T > toClazz , Registry registry ) { try { if ( toClazz . isInstance ( value ) ) { return ( T ) value ; } else if ( value instanceof BindObject ) { T bean = newInstance ( toClazz ) ; for ( Map . Entry < String , Object > entry : ( BindObject ) value ) { Class < ? > requiredType = PropertyUtils . getPropertyType ( toClazz , entry . getKey ( ) ) ; Object propValue = transform ( entry . getValue ( ) , requiredType , registry ) ; if ( propValue != null ) { PropertyUtils . writeProperty ( bean , entry . getKey ( ) , propValue ) ; } } return bean ; } else if ( value instanceof Optional ) { Optional < ? > optional = ( Optional ) value ; if ( toClazz == Optional . class ) { Class < ? > targetType = PropertyUtils . getGenericParamTypes ( toClazz ) [ 0 ] ; return ( T ) optional . map ( v -> transform ( v , targetType , registry ) ) ; } else { return transform ( optional . orElse ( null ) , toClazz , registry ) ; } } else if ( value instanceof Map ) { Map < ? , ? > values = ( Map ) value ; if ( Map . class . isAssignableFrom ( toClazz ) ) { Class < ? > keyType = PropertyUtils . getGenericParamTypes ( toClazz ) [ 0 ] ; Class < ? > valueType = PropertyUtils . getGenericParamTypes ( toClazz ) [ 1 ] ; values = values . entrySet ( ) . stream ( ) . map ( e -> entry ( transform ( e . getKey ( ) , keyType , registry ) , transform ( e . getValue ( ) , valueType , registry ) ) ) . collect ( Collectors . toMap ( Map . Entry :: getKey , Map . Entry :: getValue ) ) ; return doTransform ( values , toClazz , registry ) ; } else throw new IllegalArgumentException ( "INCOMPATIBLE transform: " + value . getClass ( ) . getName ( ) + " -> " + toClazz . getName ( ) ) ; } else if ( value instanceof Collection ) { Collection < ? > values = ( Collection ) value ; if ( Collection . class . isAssignableFrom ( toClazz ) || toClazz . isArray ( ) ) { Class < ? > elemType = toClazz . isArray ( ) ? toClazz . getComponentType ( ) : PropertyUtils . getGenericParamTypes ( toClazz ) [ 0 ] ; values = values . stream ( ) . map ( v -> transform ( v , elemType , registry ) ) . collect ( Collectors . < Object > toList ( ) ) ; return doTransform ( values , toClazz , registry ) ; } else throw new IllegalArgumentException ( "INCOMPATIBLE transform: " + value . getClass ( ) . getName ( ) + " -> " + toClazz . getName ( ) ) ; } else { return doTransform ( value , toClazz , registry ) ; } } catch ( Exception e ) { throw new RuntimeException ( e ) ; } }
/---