@SuppressWarnings({"unchecked", "WeakerAccess"})
	public static <T> T createClientProxy(ClassLoader classLoader, Class<T> proxyInterface, final JsonRpcClient client, final InputStream input, final OutputStream output) {
		
		// create and return the proxy
		return (T) Proxy.newProxyInstance(classLoader, new Class<?>[]{proxyInterface}, new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				if (isDeclaringClassAnObject(method)) return proxyObjectMethods(method, proxy, args);
				
				final Object arguments = ReflectionUtil.parseArguments(method, args);
				final String methodName = getMethodName(method);
				return client.invokeAndReadResponse(methodName, arguments, method.getGenericReturnType(), output, input);
			}
		});
	}
@ SuppressWarnings ( { "unchecked" , "WeakerAccess" } ) public static < T > T createClientProxy ( ClassLoader classLoader , Class < T > proxyInterface , final JsonRpcClient client , final InputStream input , final OutputStream output ) { return ( T ) Proxy . newProxyInstance ( classLoader , new Class < ? > [ ] { proxyInterface } , new InvocationHandler ( ) { @ Override public Object invoke ( Object proxy , Method method , Object [ ] args ) throws Throwable { if ( isDeclaringClassAnObject ( method ) ) return proxyObjectMethods ( method , proxy , args ) ; final Object arguments = ReflectionUtil . parseArguments ( method , args ) ; final String methodName = getMethodName ( method ) ; return client . invokeAndReadResponse ( methodName , arguments , method . getGenericReturnType ( ) , output , input ) ; } } ) ; }
Creates a {@link Proxy} of the given {@code proxyInterface}
that uses the given {@link JsonRpcClient}.

@param <T>            the proxy type
@param classLoader    the {@link ClassLoader}
@param proxyInterface the interface to proxy
@param client         the {@link JsonRpcClient}
@param input          the {@link InputStream}
@param output         the {@link OutputStream}
@return the proxied interface