class ChainedConsumerAdapter<P, T, V> implements ValueIterationConsumerAdapter<P, V> {
        final private ValueIterationConsumerAdapter<? super P, T> myBeforeAdapter;
        final private ValueIterationConsumerAdapter<? super T, V> myAfterAdapter;

        public ChainedConsumerAdapter(ValueIterationConsumerAdapter<? super P, T> beforeAdapter, ValueIterationConsumerAdapter<? super T, V> afterAdapter) {
            myBeforeAdapter = beforeAdapter;
            myAfterAdapter = afterAdapter;
        }

        @NotNull
        @Override
        public <R> ValueIterationConsumer<? super P, R> getConsumer(ValueIterationConsumer<? super V, R> valueConsumer) {
            return myBeforeAdapter.getConsumer(myAfterAdapter.getConsumer(valueConsumer));
        }

        @NotNull
        @Override
        public <R> ValueIterationConsumer<? super P, R> getConsumer(VoidIterationConsumer<? super V> voidConsumer) {
            return myBeforeAdapter.getConsumer(myAfterAdapter.getConsumer(voidConsumer));
        }
    }

    public ValueIterationAdapterImpl(@NotNull Function<? super N, T> function) {
        this(function, null);
    }

    public ValueIterationAdapterImpl(@NotNull Function<? super N, T> function, @Nullable ValueIterationFilter<? super T> filter) {
        this(new ConsumerAdapter<>(function, filter));
    }

    public ValueIterationAdapterImpl(@NotNull ValueIterationConsumerAdapter<N, T> consumerAdapter) {
        myConsumerAdapter = consumerAdapter;
    }

    @NotNull
    @Override
    public ValueIterationConsumerAdapter<N, T> getConsumerAdapter() {
        return myConsumerAdapter;
    }

    @NotNull
    @Override
    public <V> ValueIterationAdapter<N, V> andThen(ValueIterationAdapter<? super T, V> after) {
        return new ValueIterationAdapterImpl<>(new ChainedConsumerAdapter<>(myConsumerAdapter, after.getConsumerAdapter()));
    }

    @NotNull
    @Override
    public ValueIterationAdapter<N, T> compose(ValueIterationAdapter<? super N, N> before) {
        return new ValueIterationAdapterImpl<>(new ChainedConsumerAdapter<>(before.getConsumerAdapter(), myConsumerAdapter));
    }

    public static <N> ValueIterationAdapter<N, N> of() {
        return new ValueIterationAdapterImpl<>(Function.identity());
    }

    public static <N> ValueIterationAdapter<N, N> of(ValueIterationFilter<? super N> filter) {
        return new ValueIterationAdapterImpl<>(Function.identity(), filter);
    }

    public static <N, T> ValueIterationAdapter<N, T> of(Function<? super N, T> function) {
        return new ValueIterationAdapterImpl<>(function);
    }

    public static <N, T> ValueIterationAdapter<N, T> of(Class<? extends T> clazz) {
        return new ValueIterationAdapterImpl<>(it -> clazz.isInstance(it) ? clazz.cast(it) : null);
    }

    public static <N, T> ValueIterationAdapter<N, T> of(Iterable<Class<? extends T>> clazzes) {<FILL_FUNCTION_BODY>

        return new ValueIterationAdapterImpl<>(it -> {
            for (Class<? extends T> clazz : clazzes) {
                if (clazz.isInstance(it)) return clazz.cast(it);
            }
            return null;
        });
    
<no_super_class>