docs: @FFDCIgnore(value = UnableToAdaptException.class)
      public void addApplication(ApplicationInstallInfo installInfo) {
          // ...and now create the new... start by asking the handler what needs monitoring
          final Collection<Notification> notificationsToMonitor;
          final boolean listenForRootStructuralChanges;
          ApplicationMonitoringInformation ami = installInfo.getApplicationMonitoringInformation();
          if (ami != null) {
              notificationsToMonitor = ami.getNotificationsToMonitor();
              listenForRootStructuralChanges = ami.isListeningForRootStructuralChanges();
          } else {
              notificationsToMonitor = null;
              listenForRootStructuralChanges = true;
          }
  
          try {
              // Now create the listeners for these notifications
              ApplicationListeners listeners = new ApplicationListeners(installInfo.getUpdateHandler(), _executorService);
  
              /*
               * Go through all of the notifications to monitor and create a listener for it. Note we also always create a different type of listener for root so if the app is
               * deleted we
               * know about it. Optionally (based on the handler) this might also monitor for files being added or removed from the root to trigger an update, i.e. if a WAR gets
               * added to
               * the root of an EAR.
               */
              if (notificationsToMonitor != null) {
                  for (Notification notificationToMonitor : notificationsToMonitor) {
                      ApplicationListener listener = new ApplicationListener(notificationToMonitor, listeners, installInfo);
                      listeners.addListener(listener);
                  }
  
                  // If the handler did request monitoring then we still need a non-recursive handler to check root
                  listeners.addListener(new RootApplicationListener(installInfo.getContainer(), listenForRootStructuralChanges, listeners));
              } else {
                  /*
                   * If the handler didn't give us any information about what to monitor then monitor the whole application, note we use another type of listener again here that will
                   * monitor for root deletions or updates to any part of the application
                   */
                  listeners.addListener(new CompleteApplicationListener(installInfo.getContainer(), listeners));
              }
  
              ApplicationListeners old = _appListeners.put(installInfo.getPid(), listeners);
  
              if (old != null) {
                  old.stopListeners(true);
              }
  
              // If we're actively scanning, start the new listener
              ApplicationMonitorConfig config = _config.get();
              if (config.getUpdateTrigger() != UpdateTrigger.DISABLED) {
                  listeners.startListeners(config.getPollingRate(), config.getUpdateTrigger() == UpdateTrigger.MBEAN);
              }
          } catch (UnableToAdaptException e) {
              // Ignore, we just won't monitor this application but do put out a warning message
              AppMessageHelper.get(installInfo.getHandler()).warning("APPLICATION_MONITORING_FAIL", installInfo.getName());
          }
      }