docs: public void execute() throws CheckedAnalysisException, IOException, InterruptedException {
          File dir = new File(rootSourceDirectory);
          if (!dir.isDirectory()) {
              throw new IOException("Path " + rootSourceDirectory + " is not a directory");
          }
  
          // Find all directories underneath the root source directory
          progress.startRecursiveDirectorySearch();
          RecursiveFileSearch rfs = new RecursiveFileSearch(rootSourceDirectory, pathname -> pathname.isDirectory());
          rfs.search();
          progress.doneRecursiveDirectorySearch();
          List<String> candidateSourceDirList = rfs.getDirectoriesScanned();
  
          // Build the classpath
  
          IClassFactory factory = ClassFactory.instance();
          IClassPathBuilder builder = factory.createClassPathBuilder(errorLogger);
  
          try (IClassPath classPath = buildClassPath(builder, factory)) {
  
              // From the application classes, find the full list of
              // fully-qualified source file names.
              List<String> fullyQualifiedSourceFileNameList = findFullyQualifiedSourceFileNames(builder, classPath);
  
              // Attempt to find source directories for all source files,
              // and add them to the discoveredSourceDirectoryList
              if (DEBUG) {
                  System.out.println("looking for " + fullyQualifiedSourceFileNameList.size() + " files");
              }
              findSourceDirectoriesForAllSourceFiles(fullyQualifiedSourceFileNameList, candidateSourceDirList);
          }
      }