class LinkkiConverterRegistry implements Serializable {

    @SuppressWarnings("unchecked")
    public <P, M> Converter<P, M> findConverter(Type presentationType, Type modelType) {
        Class<?> rawPresentationType = getRawType(presentationType);
        Class<?> rawModelType = getRawType(modelType);
        // rawPresentationType may be null if presentationType is a type variable
        if (isIdentityNecessary(rawPresentationType, rawModelType)) {
            return (Converter<P, M>)Converter.identity();
        } else {
            return converters.computeIfAbsent(rawPresentationType, t -> Sequence.empty())
                    .stream()
                    .map(Converter.class::cast)
                    .filter(c -> TypeUtils.equals(getPresentationType(c), rawPresentationType)
                            && TypeUtils.equals(rawModelType, getModelType(c)))
                    .findFirst()
                    .orElseThrow(() -> new IllegalArgumentException(
                            "Cannot convert presentation type " + rawPresentationType + " to model type "
                                    + rawModelType));
        }
    }

    @SafeVarargs public  LinkkiConverterRegistry(Converter<?, ?>... customConverters);
    public  LinkkiConverterRegistry(Collection<Converter<?, ?>> customConverters);
    public  LinkkiConverterRegistry(Sequence<Converter<?, ?>> customConverters);

}