docs: protected void loadDetachedPlugins() {
          VersionNumber lastExecVersion = new VersionNumber(InstallUtil.getLastExecVersion());
          if (lastExecVersion.isNewerThan(InstallUtil.NEW_INSTALL_VERSION) && lastExecVersion.isOlderThan(Jenkins.getVersion())) {
  
              LOGGER.log(INFO, "Upgrading Jenkins. The last running version was {0}. This Jenkins is version {1}.",
                      new Object[] {lastExecVersion, Jenkins.VERSION});
  
              final List<DetachedPluginsUtil.DetachedPlugin> detachedPlugins = DetachedPluginsUtil.getDetachedPlugins(lastExecVersion);
  
              Set<String> loadedDetached = loadPluginsFromWar("/WEB-INF/detached-plugins", new FilenameFilter() {
                  @Override
                  public boolean accept(File dir, String name) {
                      name = normalisePluginName(name);
  
                      // If this was a plugin that was detached some time in the past i.e. not just one of the
                      // plugins that was bundled "for fun".
                      if (DetachedPluginsUtil.isDetachedPlugin(name)) {
                          VersionNumber installedVersion = getPluginVersion(rootDir, name);
                          VersionNumber bundledVersion = getPluginVersion(dir, name);
                          // If the plugin is already installed, we need to decide whether to replace it with the bundled version.
                          if (installedVersion != null && bundledVersion != null) {
                              // If the installed version is older than the bundled version, then it MUST be upgraded.
                              // If the installed version is newer than the bundled version, then it MUST NOT be upgraded.
                              // If the versions are equal we just keep the installed version.
                              return installedVersion.isOlderThan(bundledVersion);
                          }
                      }
  
                      // If it's a plugin that was detached since the last running version.
                      for (DetachedPluginsUtil.DetachedPlugin detachedPlugin : detachedPlugins) {
                          if (detachedPlugin.getShortName().equals(name)) {
                              return true;
                          }
                      }
  
                      // Otherwise skip this and do not install.
                      return false;
                  }
              });
  
              LOGGER.log(INFO, "Upgraded Jenkins from version {0} to version {1}. Loaded detached plugins (and dependencies): {2}",
                      new Object[] {lastExecVersion, Jenkins.VERSION, loadedDetached});
  
              InstallUtil.saveLastExecVersion();
          } else {
              final Set<DetachedPluginsUtil.DetachedPlugin> forceUpgrade = new HashSet<>();
              // TODO using getDetachedPlugins here seems wrong; should be forcing an upgrade when the installed version is older than that in WEB-INF/detached-plugins/
              for (DetachedPluginsUtil.DetachedPlugin p : DetachedPluginsUtil.getDetachedPlugins()) {
                  VersionNumber installedVersion = getPluginVersion(rootDir, p.getShortName());
                  VersionNumber requiredVersion = p.getRequiredVersion();
                  if (installedVersion != null && installedVersion.isOlderThan(requiredVersion)) {
                      LOGGER.log(Level.WARNING,
                              "Detached plugin {0} found at version {1}, required minimum version is {2}",
                              new Object[]{p.getShortName(), installedVersion, requiredVersion});
                      forceUpgrade.add(p);
                  }
              }
              if (!forceUpgrade.isEmpty()) {
                  Set<String> loadedDetached = loadPluginsFromWar("/WEB-INF/detached-plugins", new FilenameFilter() {
                      @Override
                      public boolean accept(File dir, String name) {
                          name = normalisePluginName(name);
                          for (DetachedPluginsUtil.DetachedPlugin detachedPlugin : forceUpgrade) {
                              if (detachedPlugin.getShortName().equals(name)) {
                                  return true;
                              }
                          }
                          return false;
                      }
                  });
                  LOGGER.log(INFO, "Upgraded detached plugins (and dependencies): {0}",
                          new Object[]{loadedDetached});
              }
          }
      }