/** Process SCIs. */
  public void deploy(final DeploymentPhaseContext phaseContext)
      throws DeploymentUnitProcessingException {
    final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
    final ModuleSpecification moduleSpecification =
        deploymentUnit.getAttachment(Attachments.MODULE_SPECIFICATION);
    final ServiceModuleLoader loader =
        deploymentUnit.getAttachment(Attachments.SERVICE_MODULE_LOADER);
    if (!DeploymentTypeMarker.isType(DeploymentType.WAR, deploymentUnit)) {
      return; // Skip non web deployments
    }
    WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
    assert warMetaData != null;
    final Module module = deploymentUnit.getAttachment(Attachments.MODULE);
    if (module == null) {
      throw MESSAGES.failedToResolveModule(deploymentUnit);
    }
    final ClassLoader classLoader = module.getClassLoader();
    ScisMetaData scisMetaData = deploymentUnit.getAttachment(ScisMetaData.ATTACHMENT_KEY);
    if (scisMetaData == null) {
      scisMetaData = new ScisMetaData();
      deploymentUnit.putAttachment(ScisMetaData.ATTACHMENT_KEY, scisMetaData);
    }
    Set<ServletContainerInitializer> scis = scisMetaData.getScis();
    if (scis == null) {
      scis = new HashSet<ServletContainerInitializer>();
      scisMetaData.setScis(scis);
    }
    Map<ServletContainerInitializer, Set<Class<?>>> handlesTypes = scisMetaData.getHandlesTypes();
    if (handlesTypes == null) {
      handlesTypes = new HashMap<ServletContainerInitializer, Set<Class<?>>>();
      scisMetaData.setHandlesTypes(handlesTypes);
    }
    // Find the SCIs from shared modules
    for (ModuleDependency dependency : moduleSpecification.getSystemDependencies()) {
      try {
        Module depModule = loader.loadModule(dependency.getIdentifier());
        ServiceLoader<ServletContainerInitializer> serviceLoader =
            depModule.loadService(ServletContainerInitializer.class);
        for (ServletContainerInitializer service : serviceLoader) {
          scis.add(service);
        }
      } catch (ModuleLoadException e) {
        if (dependency.isOptional() == false) {
          throw MESSAGES.errorLoadingSCIFromModule(dependency.getIdentifier(), e);
        }
      }
    }
    // Find local ServletContainerInitializer services
    List<String> order = warMetaData.getOrder();
    Map<String, VirtualFile> localScis = warMetaData.getScis();
    if (order != null && localScis != null) {
      for (String jar : order) {
        VirtualFile sci = localScis.get(jar);
        if (sci != null) {
          ServletContainerInitializer service = loadSci(classLoader, sci, jar, true);
          if (service != null) {
            scis.add(service);
          }
        }
      }
    }
    // Process HandlesTypes for ServletContainerInitializer
    Map<Class<?>, Set<ServletContainerInitializer>> typesMap =
        new HashMap<Class<?>, Set<ServletContainerInitializer>>();
    for (ServletContainerInitializer service : scis) {
      if (service.getClass().isAnnotationPresent(HandlesTypes.class)) {
        HandlesTypes handlesTypesAnnotation = service.getClass().getAnnotation(HandlesTypes.class);
        Class<?>[] typesArray = handlesTypesAnnotation.value();
        if (typesArray != null) {
          for (Class<?> type : typesArray) {
            Set<ServletContainerInitializer> servicesSet = typesMap.get(type);
            if (servicesSet == null) {
              servicesSet = new HashSet<ServletContainerInitializer>();
              typesMap.put(type, servicesSet);
            }
            servicesSet.add(service);
            handlesTypes.put(service, new HashSet<Class<?>>());
          }
        }
      }
    }
    Class<?>[] typesArray = typesMap.keySet().toArray(new Class<?>[0]);

    final CompositeIndex index =
        deploymentUnit.getAttachment(Attachments.COMPOSITE_ANNOTATION_INDEX);
    if (index == null) {
      throw MESSAGES.unableToResolveAnnotationIndex(deploymentUnit);
    }

    // Find classes which extend, implement, or are annotated by HandlesTypes
    for (Class<?> type : typesArray) {
      DotName className = DotName.createSimple(type.getName());
      Set<ClassInfo> classInfos = processHandlesType(className, type, index);
      Set<Class<?>> classes = loadClassInfoSet(classInfos, classLoader);
      Set<ServletContainerInitializer> sciSet = typesMap.get(type);
      for (ServletContainerInitializer sci : sciSet) {
        handlesTypes.get(sci).addAll(classes);
      }
    }
  }