code: private void addPackages(final File fileOrDirectory,
                               final SortedMap<String, SortedSet<String>> package2FileNamesMap) {
  
          for (PackageExtractor current : packageExtractors) {
  
              final FileFilter sourceFileDefinitionFilter = current.getSourceFileFilter();
  
              if (fileOrDirectory.isFile() && sourceFileDefinitionFilter.accept(fileOrDirectory)) {
  
                  // Single source file to add.
                  final String thePackage = current.getPackage(fileOrDirectory);
  
                  SortedSet<String> sourceFileNames = package2FileNamesMap.get(thePackage);
                  if (sourceFileNames == null) {
                      sourceFileNames = new TreeSet<String>();
                      package2FileNamesMap.put(thePackage, sourceFileNames);
                  }
  
                  // Done.
                  sourceFileNames.add(fileOrDirectory.getName());
  
              } else if (fileOrDirectory.isDirectory()) {
  
                  // Add the immediate source files
                  for (File currentChild : fileOrDirectory.listFiles(sourceFileDefinitionFilter)) {
                      addPackages(currentChild, package2FileNamesMap);
                  }
  
                  // Recurse into subdirectories
                  for (File currentSubdirectory : fileOrDirectory.listFiles(DIRECTORY_FILTER)) {
                      addPackages(currentSubdirectory, package2FileNamesMap);
                  }
              }
          }
      }
docs: Adds all source file found by recursive search under sourceRoot to the
  toPopulate List, using a width-first approach.
  
  @param fileOrDirectory      The file or directory to search for packages and [if a directory] recursively
  search for further source files.
  @param package2FileNamesMap A Map relating package names extracted by the PackageExtractors.