@Override
  public void handlePageException(final Throwable t) throws IOException, ServletException {
    if (t == null) throw new NullPointerException("null Throwable");

    if (SecurityUtil.isPackageProtectionEnabled()) {
      try {
        AccessController.doPrivileged(
            new PrivilegedExceptionAction<Void>() {
              @Override
              public Void run() throws Exception {
                doHandlePageException(t);
                return null;
              }
            });
      } catch (PrivilegedActionException e) {
        Exception ex = e.getException();
        if (ex instanceof IOException) {
          throw (IOException) ex;
        } else {
          throw (ServletException) ex;
        }
      }
    } else {
      doHandlePageException(t);
    }
  }
  protected Class<?> loadClassMaybePrivileged(final String className, final ClassLoader classLoader)
      throws ClassNotFoundException {
    Class<?> clazz;
    if (SecurityUtil.isPackageProtectionEnabled()) {
      try {
        clazz =
            AccessController.doPrivileged(
                new PrivilegedExceptionAction<Class<?>>() {

                  @Override
                  public Class<?> run() throws Exception {
                    return classLoader.loadClass(className);
                  }
                });
      } catch (PrivilegedActionException e) {
        Throwable t = e.getCause();
        if (t instanceof ClassNotFoundException) {
          throw (ClassNotFoundException) t;
        }
        throw new RuntimeException(t);
      }
    } else {
      clazz = classLoader.loadClass(className);
    }
    checkAccess(clazz);
    return clazz;
  }
 @Override
 public void include(final String relativeUrlPath, final boolean flush)
     throws ServletException, IOException {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     try {
       AccessController.doPrivileged(
           new PrivilegedExceptionAction<Void>() {
             @Override
             public Void run() throws Exception {
               doInclude(relativeUrlPath, flush);
               return null;
             }
           });
     } catch (PrivilegedActionException e) {
       Exception ex = e.getException();
       if (ex instanceof IOException) {
         throw (IOException) ex;
       } else {
         throw (ServletException) ex;
       }
     }
   } else {
     doInclude(relativeUrlPath, flush);
   }
 }
 public String getVirtualServerName() {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return (String) doPrivileged("getVirtualServerName", null);
   } else {
     return context.getVirtualServerName();
   }
 }
 @Override
 public String getRealPath(String path) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return (String) doPrivileged("getRealPath", new Object[] {path});
   } else {
     return context.getRealPath(path);
   }
 }
 @Override
 public void log(String msg) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     doPrivileged("log", new Object[] {msg});
   } else {
     context.log(msg);
   }
 }
 @Override
 public RequestDispatcher getRequestDispatcher(final String path) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return (RequestDispatcher) doPrivileged("getRequestDispatcher", new Object[] {path});
   } else {
     return context.getRequestDispatcher(path);
   }
 }
 @Override
 public String getInitParameter(String name) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return (String) doPrivileged("getInitParameter", new Object[] {name});
   } else {
     return context.getInitParameter(name);
   }
 }
 @Override
 public String getMimeType(String file) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return (String) doPrivileged("getMimeType", new Object[] {file});
   } else {
     return context.getMimeType(file);
   }
 }
 @Override
 public JspConfigDescriptor getJspConfigDescriptor() {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return (JspConfigDescriptor) doPrivileged("getJspConfigDescriptor", null);
   } else {
     return context.getJspConfigDescriptor();
   }
 }
 @Override
 public void addListener(String className) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     doPrivileged("addListener", new Object[] {className});
   } else {
     context.addListener(className);
   }
 }
 @Override
 public <T extends EventListener> void addListener(T t) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     doPrivileged("addListener", new Object[] {t.getClass().getName()});
   } else {
     context.addListener(t);
   }
 }
 @Override
 public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     doPrivileged("setSessionTrackingModes", new Object[] {sessionTrackingModes});
   } else {
     context.setSessionTrackingModes(sessionTrackingModes);
   }
 }
 @Override
 public void addListener(Class<? extends EventListener> listenerClass) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     doPrivileged("addListener", new Object[] {listenerClass.getName()});
   } else {
     context.addListener(listenerClass);
   }
 }
 @Override
 public Object getAttribute(String name) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return doPrivileged("getAttribute", new Object[] {name});
   } else {
     return context.getAttribute(name);
   }
 }
 @Override
 public SessionCookieConfigImpl getSessionCookieConfig() {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return (SessionCookieConfigImpl) doPrivileged("getSessionCookieConfig", null);
   } else {
     return context.getSessionCookieConfig();
   }
 }
 @Override
 public InputStream getResourceAsStream(String path) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return (InputStream) doPrivileged("getResourceAsStream", new Object[] {path});
   } else {
     return context.getResourceAsStream(path);
   }
 }
 @Override
 public FilterRegistration getFilterRegistration(String filterName) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return (FilterRegistration) doPrivileged("getFilterRegistration", new Object[] {filterName});
   } else {
     return context.getFilterRegistration(filterName);
   }
 }
 @Override
 public String getServletContextName() {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return (String) doPrivileged("getServletContextName", null);
   } else {
     return context.getServletContextName();
   }
 }
 @Override
 public int getEffectiveMinorVersion() {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return ((Integer) doPrivileged("getEffectiveMinorVersion", null)).intValue();
   } else {
     return context.getEffectiveMinorVersion();
   }
 }
 @Override
 public void removeAttribute(String name) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     doPrivileged("removeAttribute", new Object[] {name});
   } else {
     context.removeAttribute(name);
   }
 }
 @Override
 public void setAttribute(String name, Object object) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     doPrivileged("setAttribute", new Object[] {name, object});
   } else {
     context.setAttribute(name, object);
   }
 }
 @Override
 public ClassLoader getClassLoader() {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return (ClassLoader) doPrivileged("getClassLoader", null);
   } else {
     return context.getClassLoader();
   }
 }
 @Override
 public void declareRoles(String... roleNames) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     // FIXME
     doPrivileged("declareRoles", new Object[] {roleNames});
   } else {
     context.declareRoles(roleNames);
   }
 }
 @Override
 public void log(String message, Throwable throwable) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     doPrivileged(
         "log", new Class[] {String.class, Throwable.class}, new Object[] {message, throwable});
   } else {
     context.log(message, throwable);
   }
 }
 @Override
 public ServletRegistration.Dynamic addServlet(String servletName, String className) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return (ServletRegistration.Dynamic)
         doPrivileged("addServlet", new Object[] {servletName, className});
   } else {
     return context.addServlet(servletName, className);
   }
 }
 @Override
 public boolean setInitParameter(String name, String value) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return ((Boolean) doPrivileged("setInitParameter", new Object[] {name, value}))
         .booleanValue();
   } else {
     return context.setInitParameter(name, value);
   }
 }
 @Override
 public ServletRegistration getServletRegistration(String servletName) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return (ServletRegistration)
         doPrivileged("getServletRegistration", new Object[] {servletName});
   } else {
     return context.getServletRegistration(servletName);
   }
 }
 @Override
 public FilterRegistration.Dynamic addFilter(String filterName, String className) {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return (FilterRegistration.Dynamic)
         doPrivileged("addFilter", new Object[] {filterName, className});
   } else {
     return context.addFilter(filterName, className);
   }
 }
 @Override
 @SuppressWarnings("unchecked")
 // doPrivileged() returns the correct type
 public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() {
   if (SecurityUtil.isPackageProtectionEnabled()) {
     return (EnumSet<SessionTrackingMode>) doPrivileged("getEffectiveSessionTrackingModes", null);
   } else {
     return context.getEffectiveSessionTrackingModes();
   }
 }