class InvocationProxyFactory {

    private final List<MethodInterceptor> interceptors = new ArrayList<>();

    private final List<Class<?>> interfaces = new ArrayList<>();

    /**
     * Create a proxy instance give a {@link ClassLoader}.
     *
     * @param classLoader must not be {@code null}.
     * @param <T> inferred result type.
     * @return the invocation proxy instance.
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public <T> T createProxy(ClassLoader classLoader) {<FILL_FUNCTION_BODY>}

    /**
     * Add a interface type that should be implemented by the resulting invocation proxy.
     *
     * @param ifc must not be {@code null} and must be an interface type.
     */
    public void addInterface(Class<?> ifc) {

        LettuceAssert.notNull(ifc, "Interface type must not be null");
        LettuceAssert.isTrue(ifc.isInterface(), "Type must be an interface");

        this.interfaces.add(ifc);
    }

    /**
     * Add a {@link MethodInterceptor} to the interceptor chain.
     *
     * @param interceptor notNull
     */
    public void addInterceptor(MethodInterceptor interceptor) {

        LettuceAssert.notNull(interceptor, "MethodInterceptor must not be null");

        this.interceptors.add(interceptor);
    }

    /**
     * {@link MethodInterceptor}-based {@link InterceptorChainInvocationHandler}.
     */
    static class InterceptorChainInvocationHandler extends AbstractInvocationHandler {

        private final MethodInterceptorChain.Head context;

        InterceptorChainInvocationHandler(List<MethodInterceptor> interceptors) {
            this.context = MethodInterceptorChain.from(interceptors);
        }

        @Override
        protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
            return context.invoke(proxy, method, args);
        }

    }

}


        LettuceAssert.notNull(classLoader, "ClassLoader must not be null");

        Class<?>[] interfaces = this.interfaces.toArray(new Class[0]);

        return (T) Proxy.newProxyInstance(classLoader, interfaces, new InterceptorChainInvocationHandler(interceptors));
    
<no_super_class>