docs: @Override
      public Result resolveFeatures(Repository repository, Collection<ProvisioningFeatureDefinition> kernelFeatures, Collection<String> rootFeatures, Set<String> preResolved,
                                    boolean allowMultipleVersions,
                                    EnumSet<ProcessType> supportedProcessTypes) {
          SelectionContext selectionContext = new SelectionContext(repository, allowMultipleVersions, supportedProcessTypes);
  
          // this checks if the pre-resolved exists in the repo;
          // if one does not exist then we start over with an empty set of pre-resolved
          preResolved = checkPreResolvedExistAndSetFullName(preResolved, selectionContext);
  
          // check that the root features exist and are public; remove them if not; also get the full name
          rootFeatures = checkRootsAreAccessibleAndSetFullName(new ArrayList<String>(rootFeatures), selectionContext, preResolved);
  
          // Always prime the selected with the pre-resolved and the root features.
          // This will ensure that the root and pre-resolved features do not conflict
          selectionContext.primeSelected(preResolved);
          selectionContext.primeSelected(rootFeatures);
  
          // Even if the feature set hasn't changed, we still need to process the auto features and add any features that need to be
          // installed/uninstalled to the list. This recursively iterates over the auto Features, as previously installed features
          // may satisfy other auto features.
          Set<String> autoFeaturesToInstall = Collections.<String> emptySet();
          Set<String> seenAutoFeatures = new HashSet<String>();
          Set<String> resolved = Collections.emptySet();
  
          do {
              if (!!!autoFeaturesToInstall.isEmpty()) {
                  // this is after the first pass;  use the autoFeaturesToInstall as the roots
                  rootFeatures = autoFeaturesToInstall;
                  // Need to prime the auto features as selected
                  selectionContext.primeSelected(autoFeaturesToInstall);
                  // and use the resolved as the preResolved
                  preResolved = resolved;
                  // A new resolution process will happen now along with the auto-features that match;
                  // need to save off the current conflicts to be the pre resolved conflicts
                  // otherwise they would get lost
                  selectionContext.saveCurrentPreResolvedConflicts();
              }
              resolved = doResolveFeatures(rootFeatures, preResolved, selectionContext);
          } while (!!!(autoFeaturesToInstall = processAutoFeatures(kernelFeatures, resolved, seenAutoFeatures, selectionContext)).isEmpty());
          // Finally return the selected result
          return selectionContext.getResult();
      }