protected void initCustomJspBag(String contextId, String contextName, CustomJspBag customJspBag)
      throws Exception {

    String customJspDir = customJspBag.getCustomJspDir();
    boolean customJspGlobal = customJspBag.isCustomJspGlobal();
    List<String> customJsps = customJspBag.getCustomJsps();

    String portalWebDir = PortalUtil.getPortalWebDir();

    for (String customJsp : customJsps) {
      String portalJsp = getPortalJsp(customJsp, customJspDir);

      if (customJspGlobal) {
        File portalJspFile = new File(portalWebDir + portalJsp);
        File portalJspBackupFile = getPortalJspBackupFile(portalJspFile);

        if (portalJspFile.exists() && !portalJspBackupFile.exists()) {
          FileUtil.copyFile(portalJspFile, portalJspBackupFile);
        }
      } else {
        portalJsp = CustomJspRegistryUtil.getCustomJspFileName(contextId, portalJsp);
      }

      FileUtil.write(
          portalWebDir + portalJsp,
          getCustomJspInputStream(customJspBag.getURLContainer(), customJsp));
    }

    if (!customJspGlobal) {
      CustomJspRegistryUtil.registerServletContextName(contextId, contextName);
    }
  }
    @Override
    public void removedService(
        ServiceReference<CustomJspBag> serviceReference, CustomJspBag customJspBag) {

      Registry registry = RegistryUtil.getRegistry();

      registry.ungetService(serviceReference);

      String contextId = GetterUtil.getString(serviceReference.getProperty("context.id"));

      for (String customJsp : customJspBag.getCustomJsps()) {
        String customJspDir = customJspBag.getCustomJspDir();

        int pos = customJsp.indexOf(customJspDir);

        String portalJsp = customJsp.substring(pos + customJspDir.length());

        if (customJspBag.isCustomJspGlobal()) {
          File portalJspFile = new File(PortalUtil.getPortalWebDir() + portalJsp);
          File portalJspBackupFile = getPortalJspBackupFile(portalJspFile);

          if (portalJspBackupFile.exists()) {
            try {
              FileUtil.copyFile(portalJspBackupFile, portalJspFile);
            } catch (IOException e) {
              return;
            }

            portalJspBackupFile.delete();
          } else if (portalJspFile.exists()) {
            portalJspFile.delete();
          }
        } else {
          portalJsp = CustomJspRegistryUtil.getCustomJspFileName(contextId, portalJsp);

          File portalJspFile = new File(PortalUtil.getPortalWebDir() + portalJsp);

          if (portalJspFile.exists()) {
            portalJspFile.delete();
          }
        }
      }

      if (!customJspBag.isCustomJspGlobal()) {
        CustomJspRegistryUtil.unregisterServletContextName(contextId);
      }

      _customJspBagsMap.remove(serviceReference);
    }
    @Override
    public CustomJspBag addingService(ServiceReference<CustomJspBag> serviceReference) {

      Registry registry = RegistryUtil.getRegistry();

      CustomJspBag customJspBag = registry.getService(serviceReference);

      List<String> customJsps = customJspBag.getCustomJsps();

      if (customJsps.isEmpty()) {
        getCustomJsps(
            customJspBag.getURLContainer(),
            customJspBag.getCustomJspDir(),
            customJspBag.getCustomJsps());

        customJsps = customJspBag.getCustomJsps();

        if (customJsps.isEmpty()) {
          return null;
        }
      }

      if (_log.isDebugEnabled()) {
        StringBundler sb = new StringBundler(customJsps.size() * 2);

        sb.append("Custom JSP files:\n");

        for (int i = 0; i < customJsps.size(); i++) {
          String customJsp = customJsps.get(0);

          sb.append(customJsp);

          if ((i + 1) < customJsps.size()) {
            sb.append(StringPool.NEW_LINE);
          }
        }

        Log log = SanitizerLogWrapper.allowCRLF(_log);

        log.debug(sb.toString());
      }

      String contextId = GetterUtil.getString(serviceReference.getProperty("context.id"));

      if (customJspBag.isCustomJspGlobal() && !_customJspBagsMap.isEmpty()) {

        try {
          verifyCustomJsps(contextId, customJspBag);
        } catch (DuplicateCustomJspException e) {
          return null;
        }
      }

      _customJspBagsMap.put(serviceReference, customJspBag);

      String contextName = GetterUtil.getString(serviceReference.getProperty("context.name"));

      try {
        initCustomJspBag(contextId, contextName, customJspBag);
      } catch (Exception e) {
        return null;
      }

      return customJspBag;
    }
  protected void verifyCustomJsps(String contextId, CustomJspBag customJspBag)
      throws DuplicateCustomJspException {

    Set<String> customJsps = new HashSet<>();

    for (String customJsp : customJspBag.getCustomJsps()) {
      String portalJsp = getPortalJsp(customJsp, customJspBag.getCustomJspDir());

      customJsps.add(portalJsp);
    }

    Map<String, String> conflictingCustomJsps = new HashMap<>();

    for (Map.Entry<ServiceReference<CustomJspBag>, CustomJspBag> entry :
        _customJspBagsMap.entrySet()) {

      CustomJspBag currentCustomJspBag = entry.getValue();

      if (!currentCustomJspBag.isCustomJspGlobal()) {
        continue;
      }

      ServiceReference<CustomJspBag> serviceReference = entry.getKey();

      String contextName = GetterUtil.getString(serviceReference.getProperty("context.name"));

      List<String> currentCustomJsps = currentCustomJspBag.getCustomJsps();

      for (String currentCustomJsp : currentCustomJsps) {
        String currentPortalJsp =
            getPortalJsp(currentCustomJsp, currentCustomJspBag.getCustomJspDir());

        if (customJsps.contains(currentPortalJsp)) {
          conflictingCustomJsps.put(currentPortalJsp, contextName);
        }
      }
    }

    if (conflictingCustomJsps.isEmpty()) {
      return;
    }

    _log.error(contextId + " conflicts with the installed hooks");

    if (_log.isDebugEnabled()) {
      Log log = SanitizerLogWrapper.allowCRLF(_log);

      StringBundler sb = new StringBundler(conflictingCustomJsps.size() * 4 + 2);

      sb.append("Colliding JSP files in ");
      sb.append(contextId);
      sb.append(StringPool.NEW_LINE);

      int i = 0;

      for (Map.Entry<String, String> entry : conflictingCustomJsps.entrySet()) {

        sb.append(entry.getKey());
        sb.append(" with ");
        sb.append(entry.getValue());

        if ((i + 1) < conflictingCustomJsps.size()) {
          sb.append(StringPool.NEW_LINE);
        }

        i++;
      }

      log.debug(sb.toString());
    }

    throw new DuplicateCustomJspException();
  }