docs: public static DiskInterface createLoggingProxy(final DiskInterface impl) {
  
          return (DiskInterface)Proxy.newProxyInstance(
              Thread.currentThread().getContextClassLoader(),
              new Class[] {DiskInterface.class},
              new InvocationHandler() {
  
                  @SuppressWarnings("synthetic-access")
                  public Object invoke(Object target, Method method, Object[] params) throws Throwable {
  
                      // Just to be on the safe side performance-wise, we only log the parameters/result
                      // if the info channel is enabled
                      if (LOG.isInfoEnabled()) {
                          List<String> paramStrings = new ArrayList<String>();
                          for (Object param : params) {
                              paramStrings.add("" + param);
                          }
                          String paramsAsString = CmsStringUtil.listAsString(paramStrings, ", ");
                          LOG.info("Call: " + method.getName() + " " + paramsAsString);
                      }
                      try {
                          Object result = method.invoke(impl, params);
                          if (LOG.isInfoEnabled()) {
                              LOG.info("Returned from " + method.getName() + ": " + result);
                          }
                          return result;
                      } catch (InvocationTargetException e) {
                          Throwable cause = e.getCause();
                          if ((cause != null) && (cause instanceof CmsSilentWrapperException)) {
                              // not really an error
                              LOG.info(cause.getCause().getLocalizedMessage(), cause.getCause());
                          } else {
                              LOG.error(e.getLocalizedMessage(), e);
                          }
                          throw e.getCause();
                      }
                  }
              });
      }