gt:             if (!isScanBootstrapClassPath()) {
context: /*
   *  Licensed to the Apache Software Foundation (ASF) under one or more
   *  contributor license agreements.  See the NOTICE file distributed with
   *  this work for additional information regarding copyright ownership.
   *  The ASF licenses this file to You under the Apache License, Version 2.0
   *  (the "License"); you may not use this file except in compliance with
   *  the License.  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   */
  package org.apache.tomcat.util.scan;
  
  import java.io.File;
  import java.io.IOException;
  import java.net.JarURLConnection;
  import java.net.MalformedURLException;
  import java.net.URISyntaxException;
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.net.URLConnection;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.Set;
  
  import javax.servlet.ServletContext;
  
  import org.apache.juli.logging.Log;
  import org.apache.juli.logging.LogFactory;
  import org.apache.tomcat.JarScanFilter;
  import org.apache.tomcat.JarScanType;
  import org.apache.tomcat.JarScanner;
  import org.apache.tomcat.JarScannerCallback;
  import org.apache.tomcat.util.res.StringManager;
  
  /**
   * The default {@link JarScanner} implementation scans the WEB-INF/lib directory
   * followed by the provided classloader and then works up the classloader
   * hierarchy. This implementation is sufficient to meet the requirements of the
   * Servlet 3.0 specification as well as to provide a number of Tomcat specific
   * extensions. The extensions are:
   * <ul>
   *   <li>Scanning the classloader hierarchy (enabled by default)</li>
   *   <li>Testing all files to see if they are JARs (disabled by default)</li>
   *   <li>Testing all directories to see if they are exploded JARs
   *       (disabled by default)</li>
   * </ul>
   * All of the extensions may be controlled via configuration.
   */
  public class StandardJarScanner implements JarScanner {
  
      private static final Log log = LogFactory.getLog(StandardJarScanner.class);
  
      /**
       * The string resources for this package.
       */
      private static final StringManager sm =
          StringManager.getManager(Constants.Package);
  
      /**
       * Controls the classpath scanning extension.
       */
      private boolean scanClassPath = true;
      public boolean isScanClassPath() {
          return scanClassPath;
      }
      public void setScanClassPath(boolean scanClassPath) {
          this.scanClassPath = scanClassPath;
      }
  
      /**
       * Controls the testing all files to see of they are JAR files extension.
       */
      private boolean scanAllFiles = false;
      public boolean isScanAllFiles() {
          return scanAllFiles;
      }
      public void setScanAllFiles(boolean scanAllFiles) {
          this.scanAllFiles = scanAllFiles;
      }
  
      /**
       * Controls the testing all directories to see of they are exploded JAR
       * files extension.
       */
      private boolean scanAllDirectories = false;
      public boolean isScanAllDirectories() {
          return scanAllDirectories;
      }
      public void setScanAllDirectories(boolean scanAllDirectories) {
          this.scanAllDirectories = scanAllDirectories;
      }
  
      /**
       * Controls the testing of the bootstrap classpath which consists of the
       * runtime classes provided by the JVM and any installed system extensions.
       */
      private boolean scanBootstrapClassPath = false;
      public boolean isScanBootstrapClassPath() {
          return scanBootstrapClassPath;
      }
      public void setScanBootstrapClassPath(boolean scanBootstrapClassPath) {
          this.scanBootstrapClassPath = scanBootstrapClassPath;
      }
  
      /**
       * Controls the filtering of the results from the scan for JARs
       */
      private JarScanFilter jarScanFilter = new StandardJarScanFilter();
      @Override
      public JarScanFilter getJarScanFilter() {
          return jarScanFilter;
      }
      @Override
      public void setJarScanFilter(JarScanFilter jarScanFilter) {
          this.jarScanFilter = jarScanFilter;
      }
  
      /**
       * Scan the provided ServletContext and class loader for JAR files. Each JAR
       * file found will be passed to the callback handler to be processed.
       *
       * @param scanType      The type of JAR scan to perform. This is passed to
       *                          the filter which uses it to determine how to
       *                          filter the results
       * @param context       The ServletContext - used to locate and access
       *                      WEB-INF/lib
       * @param callback      The handler to process any JARs found
       */
      @Override
      public void scan(JarScanType scanType, ServletContext context,
              JarScannerCallback callback) {
  
          if (log.isTraceEnabled()) {
              log.trace(sm.getString("jarScan.webinflibStart"));
          }
  
          Set<URL> processedURLs = new HashSet<>();
  
          // Scan WEB-INF/lib
          Set<String> dirList = context.getResourcePaths(Constants.WEB_INF_LIB);
          if (dirList != null) {
              Iterator<String> it = dirList.iterator();
              while (it.hasNext()) {
                  String path = it.next();
                  if (path.endsWith(Constants.JAR_EXT) &&
                          getJarScanFilter().check(scanType,
                                  path.substring(path.lastIndexOf('/')+1))) {
                      // Need to scan this JAR
                      if (log.isDebugEnabled()) {
                          log.debug(sm.getString("jarScan.webinflibJarScan", path));
                      }
                      URL url = null;
                      try {
                          url = context.getResource(path);
                          processedURLs.add(url);
                          process(scanType, callback, url, path, true);
                      } catch (IOException e) {
                          log.warn(sm.getString("jarScan.webinflibFail", url), e);
                      }
                  } else {
                      if (log.isTraceEnabled()) {
                          log.trace(sm.getString("jarScan.webinflibJarNoScan", path));
                      }
                  }
              }
          }
  
          // Scan WEB-INF/classes
          if (isScanAllDirectories()) {
              try {
                  URL url = context.getResource("/WEB-INF/classes/META-INF");
                  if (url != null) {
                      // Class path scanning will look at WEB-INF/classes since
                      // that is the URL that Tomcat's web application class
                      // loader returns. Therefore, it is this URL that needs to
                      // be added to the set of processed URLs.
                      URL webInfURL = context.getResource("/WEB-INF/classes");
                      if (webInfURL != null) {
                          processedURLs.add(webInfURL);
                      }
                      try {
                          callback.scanWebInfClasses();
                      } catch (IOException e) {
                          log.warn(sm.getString("jarScan.webinfclassesFail"), e);
                      }
                  }
              } catch (MalformedURLException e) {
                  // Ignore
              }
          }
  
          // Scan the classpath
          if (isScanClassPath()) {
              if (log.isTraceEnabled()) {
                  log.trace(sm.getString("jarScan.classloaderStart"));
              }
  
              ClassLoader stopLoader = null;
  