docs: @Override
      protected void processFromScratch(
          ClassSource_Streamer streamer,
          Set<String> i_seedClassNames,
          ScanPolicy scanPolicy) {
  
          String methodName = "processFromScratch";
          if (tc.isEntryEnabled()) {
              Tr.entry(tc, methodName, MessageFormat.format("[ {0} ] ENTER", getHashText()));
          }
  
          // ++ JANDEX
          //
          // A simple class source must be provided with a JANDEX index, if one is to be
          // used.
          //
          // ++ JANDEX
  
          startTimings();
  
          int initialClasses = i_seedClassNames.size();
  
          for ( String nextResourceName : provider.getResourceNames() ) {
              if ( isDirectoryResource(nextResourceName) ) {
                  incrementResourceExclusionCount();
  
                  // Mark all directories as non-root containers;
                  // Note that root containers are not currently possible for jar elements.
  
                  markResult(ClassSource_ScanCounts.ResultField.CONTAINER);
                  markResult(ClassSource_ScanCounts.ResultField.NON_ROOT_CONTAINER);
  
              } else {
                  if ( !isClassResource(nextResourceName) ) {
                      incrementResourceExclusionCount();
  
                      markResult(ClassSource_ScanCounts.ResultField.NON_CLASS);
  
                  } else {
                      // Processing notes:
                      //
                      // Make sure to record the class before attempting processing.
                      //
                      // Only one version of the class is to be processed, even if processing
                      // fails on that one version.
                      //
                      // That is, if two child class sources have versions of a class, and
                      // the version from the first class source is non-valid, the version
                      // of the class in the second class source is still masked by the
                      // version in the first class source.
  
                      String nextClassName = getClassNameFromResourceName(nextResourceName);
                      if ( isJava9SpecificClass(nextClassName) ) {
                          Tr.debug(tc, MessageFormat.format("[ {0} ] Unsupported class; skipping [ {1} ]", 
                                                            new Object[] { getHashText(), nextClassName }));
                          continue;
                      }
  
                      String i_nextClassName = internClassName(nextClassName);
                      boolean didAdd = i_maybeAdd(i_nextClassName, i_seedClassNames);
  
                      if ( !didAdd ) {
                          incrementClassExclusionCount();
  
                          markResult(ClassSource_ScanCounts.ResultField.DUPLICATE_CLASS);
  
                      } else {
                          incrementClassInclusionCount();
  
                          boolean didProcess;
  
                          try {
                              didProcess = process(streamer, nextClassName, nextResourceName, scanPolicy); // throws ClassSource_Exception
  
                          } catch (ClassSource_Exception e) {
                              didProcess = false;
  
                              // TODO: NEW_MESSAGE: Need a new message here.
  
                              // String eMsg = "[ " + getHashText() + " ]" +
                              //               " Failed to process entry [ " + nextResourceName + " ]" +
                              //               " under root [ " + getJarPath() + " ]" +
                              //               " for class [ " + nextClassName + " ]";
                              // CWWKC0044W: An exception occurred while scanning class and annotation data.
                              Tr.warning(tc, "ANNO_TARGETS_SCAN_EXCEPTION", e);
                          }
  
                          if ( didProcess ) {
                              markResult(ClassSource_ScanCounts.ResultField.PROCESSED_CLASS);
  
                          } else {
                              markResult(ClassSource_ScanCounts.ResultField.UNPROCESSED_CLASS);
                          }
                      }
  
                      markResult(ClassSource_ScanCounts.ResultField.CLASS);
                  }
  
                  markResult(ClassSource_ScanCounts.ResultField.NON_CONTAINER);
              }
  
              // Mark in the totals count for every entry.
              markResult(ClassSource_ScanCounts.ResultField.ENTRY);
          }
  
          int finalClasses = i_seedClassNames.size();
  
          if ( tc.isDebugEnabled() ) {
              Object[] logParms = new Object[] { getHashText(), null, null };
  
              logParms[1] = Integer.valueOf(finalClasses - initialClasses);
              Tr.debug(tc, MessageFormat.format("[ {0} ] RETURN [ {1} ] Added classes", logParms));
  
              for (ClassSource_ScanCounts.ResultField resultField : ClassSource_ScanCounts.ResultField.values()) {
                  int nextResult = getResult(resultField);
                  String nextResultTag = resultField.getTag();
  
                  logParms[1] = Integer.valueOf(nextResult);
                  logParms[2] = nextResultTag;
  
                  Tr.debug(tc, MessageFormat.format("[ {0} ]  [ {1} ] {2}", logParms));
              }
          }
  
          endTimings();
  
          if ( tc.isEntryEnabled() ) {
              Tr.exit(tc, methodName, getHashText());
          }
      }