public void visitContainerInitializer(
      WebAppContext context, ContainerInitializer containerInitializer) {
    if (containerInitializer == null) return;

    // add the ContainerInitializer to the list of container initializers
    List<ContainerInitializer> containerInitializers =
        (List<ContainerInitializer>)
            context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS);
    if (containerInitializers == null) {
      containerInitializers = new ArrayList<ContainerInitializer>();
      context.setAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS, containerInitializers);
    }

    containerInitializers.add(containerInitializer);

    // Ensure a bean is set up on the context that will invoke the ContainerInitializers as the
    // context starts
    ServletContainerInitializersStarter starter =
        (ServletContainerInitializersStarter)
            context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZER_STARTER);
    if (starter == null) {
      starter = new ServletContainerInitializersStarter(context);
      context.setAttribute(AnnotationConfiguration.CONTAINER_INITIALIZER_STARTER, starter);
      context.addBean(starter, true);
    }
  }
  /**
   * @param context
   * @param scis
   * @throws Exception
   */
  public void createServletContainerInitializerAnnotationHandlers(
      WebAppContext context, List<ServletContainerInitializer> scis) throws Exception {
    if (scis == null || scis.isEmpty()) return; // nothing to do

    List<ContainerInitializer> initializers = new ArrayList<ContainerInitializer>();
    context.setAttribute(CONTAINER_INITIALIZERS, initializers);

    for (ServletContainerInitializer service : scis) {
      HandlesTypes annotation = service.getClass().getAnnotation(HandlesTypes.class);
      ContainerInitializer initializer = null;
      if (annotation != null) {
        // There is a HandlesTypes annotation on the on the ServletContainerInitializer
        Class<?>[] classes = annotation.value();
        if (classes != null) {
          initializer = new ContainerInitializer(service, classes);

          // If we haven't already done so, we need to register a handler that will
          // process the whole class hierarchy to satisfy the ServletContainerInitializer
          if (context.getAttribute(CLASS_INHERITANCE_MAP) == null) {
            // MultiMap<String> map = new MultiMap<>();
            ConcurrentHashMap<String, ConcurrentHashSet<String>> map = new ClassInheritanceMap();
            context.setAttribute(CLASS_INHERITANCE_MAP, map);
            _classInheritanceHandler = new ClassInheritanceHandler(map);
          }

          for (Class<?> c : classes) {
            // The value of one of the HandlesTypes classes is actually an Annotation itself so
            // register a handler for it
            if (c.isAnnotation()) {
              if (LOG.isDebugEnabled())
                LOG.debug("Registering annotation handler for " + c.getName());
              _containerInitializerAnnotationHandlers.add(
                  new ContainerInitializerAnnotationHandler(initializer, c));
            }
          }
        } else {
          initializer = new ContainerInitializer(service, null);
          if (LOG.isDebugEnabled())
            LOG.debug("No classes in HandlesTypes on initializer " + service.getClass());
        }
      } else {
        initializer = new ContainerInitializer(service, null);
        if (LOG.isDebugEnabled()) LOG.debug("No annotation on initializer " + service.getClass());
      }

      initializers.add(initializer);
    }

    // add a bean to the context which will call the servletcontainerinitializers when appropriate
    ServletContainerInitializersStarter starter =
        (ServletContainerInitializersStarter) context.getAttribute(CONTAINER_INITIALIZER_STARTER);
    if (starter != null)
      throw new IllegalStateException("ServletContainerInitializersStarter already exists");
    starter = new ServletContainerInitializersStarter(context);
    context.setAttribute(CONTAINER_INITIALIZER_STARTER, starter);
    context.addBean(starter, true);
  }
  static WebAppContext newWebAppContext() throws MalformedURLException {
    final WebAppContext handler = new WebAppContext();
    handler.setContextPath("/");
    handler.setBaseResource(Resource.newClassPathResource("/tomcat_service"));
    handler.setClassLoader(
        new URLClassLoader(
            new URL[] {
              Resource.newClassPathResource("/tomcat_service/WEB-INF/lib/hello.jar")
                  .getURI()
                  .toURL()
            },
            JettyService.class.getClassLoader()));

    handler.addBean(new ServletContainerInitializersStarter(handler), true);
    handler.setAttribute(
        "org.eclipse.jetty.containerInitializers",
        Collections.singletonList(new ContainerInitializer(new JettyJasperInitializer(), null)));
    return handler;
  }