/**
  * Creates a wrapper that implements either {@code ServletRequest} or {@code HttpServletRequest},
  * depending on the type of {@code pImplementation.getRequest()}.
  *
  * @param pImplementation the servlet request to create a wrapper for
  * @return a {@code ServletResponse} or {@code HttpServletResponse}, depending on the type of
  *     {@code pImplementation.getResponse()}
  */
 public static ServletRequest createWrapper(final ServletRequestWrapper pImplementation) {
   // TODO: Get all interfaces from implementation
   if (pImplementation.getRequest() instanceof HttpServletRequest) {
     return (HttpServletRequest)
         Proxy.newProxyInstance(
             pImplementation.getClass().getClassLoader(),
             new Class[] {HttpServletRequest.class, ServletRequest.class},
             new HttpServletRequestHandler(pImplementation));
   }
   return pImplementation;
 }
  /**
   * Set the request that we are wrapping.
   *
   * @param request The new wrapped request
   */
  public void setRequest(ServletRequest request) {

    super.setRequest(request);

    // Initialize the attributes for this request
    synchronized (attributes) {
      attributes.clear();
      Enumeration names = request.getAttributeNames();
      while (names.hasMoreElements()) {
        String name = (String) names.nextElement();
        Object value = request.getAttribute(name);
        attributes.put(name, value);
      }
    }
  }
    public Object invoke(final Object pProxy, final Method pMethod, final Object[] pArgs)
        throws Throwable {
      try {
        // TODO: Allow partial implementing?
        if (pMethod.getDeclaringClass().isInstance(request)) {
          return pMethod.invoke(request, pArgs);
        }

        // Method is not implemented in wrapper
        return pMethod.invoke(request.getRequest(), pArgs);
      } catch (InvocationTargetException e) {
        // Unwrap, to avoid UndeclaredThrowableException...
        throw e.getTargetException();
      }
    }