Remove FilesToCompileProvider and CompilationPrerequisitesProvider and replace them with output groups.

--
MOS_MIGRATED_REVID=87038548
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java b/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
index bbe3f5f..5794965 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
@@ -789,7 +789,9 @@
   private static void scheduleTestsIfRequested(Collection<ConfiguredTarget> targetsToTest,
       Collection<ConfiguredTarget> targetsToTestExclusive, TopLevelArtifactContext topLevelOptions,
       Collection<ConfiguredTarget> allTestTargets) {
-    if (!topLevelOptions.compileOnly() && !topLevelOptions.compilationPrerequisitesOnly()
+    Set<String> outputGroups = topLevelOptions.outputGroups();
+    if (!outputGroups.contains(TopLevelArtifactProvider.FILES_TO_COMPILE)
+        && !outputGroups.contains(TopLevelArtifactProvider.COMPILATION_PREREQUISITES)
         && allTestTargets != null) {
       scheduleTests(targetsToTest, targetsToTestExclusive, allTestTargets,
           topLevelOptions.runTestsExclusively());
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/CompilationPrerequisitesProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/CompilationPrerequisitesProvider.java
deleted file mode 100644
index 8c3a6ce..0000000
--- a/src/main/java/com/google/devtools/build/lib/analysis/CompilationPrerequisitesProvider.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2014 Google Inc. All rights reserved.
-//
-// Licensed 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 com.google.devtools.build.lib.analysis;
-
-import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.collect.nestedset.NestedSet;
-import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-
-/**
- * A provider for compilation prerequisites of a given target.
- */
-@Immutable
-public final class CompilationPrerequisitesProvider implements TransitiveInfoProvider {
-
-  private final NestedSet<Artifact> compilationPrerequisites;
-
-  public CompilationPrerequisitesProvider(NestedSet<Artifact> compilationPrerequisites) {
-    this.compilationPrerequisites = compilationPrerequisites;
-  }
-
-  /**
-   * Returns compilation prerequisites (e.g., generated sources and headers) for a rule.
-   */
-  public NestedSet<Artifact> getCompilationPrerequisites() {
-    return compilationPrerequisites;
-  }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/FilesToCompileProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/FilesToCompileProvider.java
deleted file mode 100644
index 025392c..0000000
--- a/src/main/java/com/google/devtools/build/lib/analysis/FilesToCompileProvider.java
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 Google Inc. All rights reserved.
-//
-// Licensed 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 com.google.devtools.build.lib.analysis;
-
-import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-
-/**
- * A {@link TransitiveInfoProvider} that provides files to be built when the {@code --compile_only}
- * command line option is in effect. This is to avoid expensive build steps when the user only
- * wants a quick syntax check.
- */
-@Immutable
-public final class FilesToCompileProvider implements TransitiveInfoProvider {
-
-  private final ImmutableList<Artifact> filesToCompile;
-
-  public FilesToCompileProvider(ImmutableList<Artifact> filesToCompile) {
-    this.filesToCompile = filesToCompile;
-  }
-
-  /**
-   * Returns the list of artifacts to be built when the {@code --compile_only} command line option
-   * is in effect.
-   */
-  public ImmutableList<Artifact> getFilesToCompile() {
-    return filesToCompile;
-  }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
index daa24ec..5a053c6 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
@@ -56,6 +56,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.TreeMap;
 
 /**
  * Builder class for analyzed rule instances (i.e., instances of {@link ConfiguredTarget}).
@@ -65,8 +66,7 @@
   private final Map<Class<? extends TransitiveInfoProvider>, TransitiveInfoProvider> providers =
       new LinkedHashMap<>();
   private final ImmutableMap.Builder<String, Object> skylarkProviders = ImmutableMap.builder();
-  private final ImmutableMap.Builder<String, NestedSet<Artifact>> outputGroups =
-      ImmutableMap.builder();
+  private final Map<String, NestedSetBuilder<Artifact>> outputGroupBuilders = new TreeMap<>();
 
   /** These are supported by all configured targets and need to be specially handled. */
   private NestedSet<Artifact> filesToBuild = NestedSetBuilder.emptySet(Order.STABLE_ORDER);
@@ -92,9 +92,13 @@
       return null;
     }
 
-    ImmutableMap<String, NestedSet<Artifact>> outputGroupMap = outputGroups.build();
-    if (!outputGroupMap.isEmpty()) {
-      add(TopLevelArtifactProvider.class, new TopLevelArtifactProvider(outputGroupMap));
+    if (!outputGroupBuilders.isEmpty()) {
+      ImmutableMap.Builder<String, NestedSet<Artifact>> outputGroups = ImmutableMap.builder();
+      for (Map.Entry<String, NestedSetBuilder<Artifact>> entry : outputGroupBuilders.entrySet()) {
+        outputGroups.put(entry.getKey(), entry.getValue().build());
+      }
+
+      add(TopLevelArtifactProvider.class, new TopLevelArtifactProvider(outputGroups.build()));
     }
 
     FilesToRunProvider filesToRunProvider = new FilesToRunProvider(ruleContext.getLabel(),
@@ -401,19 +405,41 @@
     return this;
   }
 
+  private NestedSetBuilder<Artifact> getOutputGroupBuilder(String name) {
+    NestedSetBuilder<Artifact> result = outputGroupBuilders.get(name);
+    if (result != null) {
+      return result;
+    }
+
+    result = NestedSetBuilder.<Artifact>stableOrder();
+    outputGroupBuilders.put(name, result);
+    return result;
+  }
+
   /**
-   * Add an output group.
+   * Adds a set of files to an output group.
    */
   public RuleConfiguredTargetBuilder addOutputGroup(String name, NestedSet<Artifact> artifacts) {
-    outputGroups.put(name, artifacts);
+    getOutputGroupBuilder(name).addTransitive(artifacts);
     return this;
   }
 
   /**
-   * Add an output group.
+   * Adds a file to an output group.
    */
   public RuleConfiguredTargetBuilder addOutputGroup(String name, Artifact artifact) {
-    outputGroups.put(name, NestedSetBuilder.create(Order.STABLE_ORDER, artifact));
+    getOutputGroupBuilder(name).add(artifact);
+    return this;
+  }
+
+  /**
+   * Adds multiple output groups.
+   */
+  public RuleConfiguredTargetBuilder addOutputGroups(Map<String, NestedSet<Artifact>> groups) {
+    for (Map.Entry<String, NestedSet<Artifact>> group : groups.entrySet()) {
+      getOutputGroupBuilder(group.getKey()).addTransitive(group.getValue());
+    }
+
     return this;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactContext.java b/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactContext.java
index 85cd1a1..d4c1061 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactContext.java
@@ -27,24 +27,18 @@
 public final class TopLevelArtifactContext {
 
   public static final TopLevelArtifactContext DEFAULT = new TopLevelArtifactContext(
-      "", /*compileOnly=*/false, /*compilationPrerequisitesOnly*/false,
-      /*buildDefaultArtifacts=*/true, /*runTestsExclusively=*/false,
+      "", /*buildDefaultArtifacts=*/true, /*runTestsExclusively=*/false,
       /*outputGroups=*/ImmutableSet.<String>of(), /*shouldRunTests=*/false);
 
   private final String buildCommand;
-  private final boolean compileOnly;
-  private final boolean compilationPrerequisitesOnly;
   private final boolean buildDefaultArtifacts;
   private final boolean runTestsExclusively;
   private final ImmutableSet<String> outputGroups;
   private final boolean shouldRunTests;
 
-  public TopLevelArtifactContext(String buildCommand, boolean compileOnly,
-      boolean compilationPrerequisitesOnly, boolean filesToRun, boolean runTestsExclusively,
-      ImmutableSet<String> outputGroups, boolean shouldRunTests) {
+  public TopLevelArtifactContext(String buildCommand, boolean filesToRun,
+      boolean runTestsExclusively, ImmutableSet<String> outputGroups, boolean shouldRunTests) {
     this.buildCommand = buildCommand;
-    this.compileOnly = compileOnly;
-    this.compilationPrerequisitesOnly = compilationPrerequisitesOnly;
     this.buildDefaultArtifacts = filesToRun;
     this.runTestsExclusively = runTestsExclusively;
     this.outputGroups = outputGroups;
@@ -56,16 +50,6 @@
     return buildCommand;
   }
 
-  /** Returns the value of the --compile_only flag. */
-  public boolean compileOnly() {
-    return compileOnly;
-  }
-
-  /** Returns the value of the --compilation_prerequisites_only flag. */
-  public boolean compilationPrerequisitesOnly() {
-    return compilationPrerequisitesOnly;
-  }
-
   /** Returns the value of the (undocumented) --build_default_artifacts flag. */
   public boolean buildDefaultArtifacts() {
     return buildDefaultArtifacts;
@@ -93,8 +77,6 @@
     if (other instanceof TopLevelArtifactContext) {
       TopLevelArtifactContext otherContext = (TopLevelArtifactContext) other;
       return buildCommand.equals(otherContext.buildCommand)
-          && compileOnly == otherContext.compileOnly
-          && compilationPrerequisitesOnly == otherContext.compilationPrerequisitesOnly
           && buildDefaultArtifacts == otherContext.buildDefaultArtifacts
           && runTestsExclusively == otherContext.runTestsExclusively
           && outputGroups.equals(otherContext.outputGroups)
@@ -106,7 +88,7 @@
 
   @Override
   public int hashCode() {
-    return Objects.hash(buildCommand, compileOnly, compilationPrerequisitesOnly,
-        buildDefaultArtifacts, runTestsExclusively, outputGroups, shouldRunTests);
+    return Objects.hash(
+        buildCommand, buildDefaultArtifacts, runTestsExclusively, outputGroups, shouldRunTests);
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactHelper.java b/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactHelper.java
index 964df0d..44d1e27 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactHelper.java
@@ -128,18 +128,9 @@
       }
     }
 
-    if (context.compileOnly()) {
-      FilesToCompileProvider provider = target.getProvider(FilesToCompileProvider.class);
-      if (provider != null) {
-        importantBuilder.addAll(provider.getFilesToCompile());
-      }
-    } else if (context.compilationPrerequisitesOnly()) {
-      CompilationPrerequisitesProvider provider =
-          target.getProvider(CompilationPrerequisitesProvider.class);
-      if (provider != null) {
-        importantBuilder.addTransitive(provider.getCompilationPrerequisites());
-      }
-    } else if (context.buildDefaultArtifacts()) {
+    if (context.buildDefaultArtifacts()
+        && !context.outputGroups().contains(TopLevelArtifactProvider.COMPILATION_PREREQUISITES)
+        && !context.outputGroups().contains(TopLevelArtifactProvider.FILES_TO_COMPILE)) {
       FilesToRunProvider filesToRunProvider = target.getProvider(FilesToRunProvider.class);
       boolean hasRunfilesSupport = false;
       if (filesToRunProvider != null) {
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactProvider.java
index c91b90f..f44fddb 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactProvider.java
@@ -38,6 +38,8 @@
 public final class TopLevelArtifactProvider implements TransitiveInfoProvider {
   public static final String HIDDEN_OUTPUT_GROUP_PREFIX = "_";
   public static final String BASELINE_COVERAGE = HIDDEN_OUTPUT_GROUP_PREFIX + "_baseline_coverage";
+  public static final String FILES_TO_COMPILE = "files_to_compile";
+  public static final String COMPILATION_PREREQUISITES = "compilation_prerequisites";
 
   private final ImmutableMap<String, NestedSet<Artifact>> outputGroups;
 
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequest.java b/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequest.java
index 4933687..4cbf5a1 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequest.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequest.java
@@ -513,7 +513,6 @@
   /** Creates a new TopLevelArtifactContext from this build request. */
   public TopLevelArtifactContext getTopLevelArtifactContext() {
     return new TopLevelArtifactContext(getCommandName(),
-        getBuildOptions().compileOnly, getBuildOptions().compilationPrerequisitesOnly,
         getBuildOptions().buildDefaultArtifacts,
         getOptions(ExecutionOptions.class).testStrategy.equals("exclusive"),
         determineOutputGroups(), shouldRunTests());
@@ -529,6 +528,14 @@
       current.add(TopLevelArtifactProvider.BASELINE_COVERAGE);
     }
 
+    if (getBuildOptions().compileOnly) {
+      current.add(TopLevelArtifactProvider.FILES_TO_COMPILE);
+    }
+
+    if (getBuildOptions().compilationPrerequisitesOnly) {
+      current.add(TopLevelArtifactProvider.COMPILATION_PREREQUISITES);
+    }
+
     return ImmutableSet.copyOf(current);
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
index 295640f..7cbe43e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
@@ -22,13 +22,12 @@
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
 import com.google.devtools.build.lib.analysis.AnalysisUtils;
-import com.google.devtools.build.lib.analysis.CompilationPrerequisitesProvider;
 import com.google.devtools.build.lib.analysis.FileProvider;
-import com.google.devtools.build.lib.analysis.FilesToCompileProvider;
 import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
 import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
 import com.google.devtools.build.lib.analysis.RuleContext;
 import com.google.devtools.build.lib.analysis.TempsProvider;
+import com.google.devtools.build.lib.analysis.TopLevelArtifactProvider;
 import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
@@ -594,7 +593,7 @@
   /**
    * Collects compilation prerequisite artifacts.
    */
-  static CompilationPrerequisitesProvider collectCompilationPrerequisites(
+  static NestedSet<Artifact> collectCompilationPrerequisites(
       RuleContext ruleContext, CppCompilationContext context) {
     // TODO(bazel-team): Use context.getCompilationPrerequisites() instead.
     NestedSetBuilder<Artifact> prerequisites = NestedSetBuilder.stableOrder();
@@ -605,7 +604,7 @@
       }
     }
     prerequisites.addTransitive(context.getDeclaredIncludeSrcs());
-    return new CompilationPrerequisitesProvider(prerequisites.build());
+    return prerequisites.build();
   }
 
   /**
@@ -711,13 +710,13 @@
             collectTransitiveCcNativeLibraries(ruleContext, linkingOutputs.getDynamicLibraries())))
         .add(InstrumentedFilesProvider.class, getInstrumentedFilesProvider(
             instrumentedObjectFiles))
-        .add(FilesToCompileProvider.class, new FilesToCompileProvider(
-            getFilesToCompile(ccCompilationOutputs)))
-        .add(CompilationPrerequisitesProvider.class,
-            collectCompilationPrerequisites(ruleContext, cppCompilationContext))
         .add(TempsProvider.class, new TempsProvider(getTemps(ccCompilationOutputs)))
         .add(CppDebugFileProvider.class, new CppDebugFileProvider(
-            dwoArtifacts.getDwoArtifacts(),
-            dwoArtifacts.getPicDwoArtifacts()));
+            dwoArtifacts.getDwoArtifacts(), dwoArtifacts.getPicDwoArtifacts()))
+        .addOutputGroup(TopLevelArtifactProvider.FILES_TO_COMPILE,
+            NestedSetBuilder.wrap(Order.STABLE_ORDER, getFilesToCompile(ccCompilationOutputs)))
+        .addOutputGroup(TopLevelArtifactProvider.COMPILATION_PREREQUISITES,
+            collectCompilationPrerequisites(ruleContext, cppCompilationContext));
+
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
index 81cd014..d85a6fa 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
@@ -259,6 +259,7 @@
     targetBuilder
         .setFilesToBuild(filesToBuild)
         .addProviders(info.getProviders())
+        .addOutputGroups(info.getOutputGroups())
         .add(InstrumentedFilesProvider.class, instrumentedFilesProvider)
         .add(RunfilesProvider.class, RunfilesProvider.withData(staticRunfiles, sharedRunfiles))
         // Remove this?
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java
index cc36586..4d71798 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java
@@ -18,18 +18,18 @@
 import com.google.common.base.Preconditions;
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.AnalysisUtils;
-import com.google.devtools.build.lib.analysis.CompilationPrerequisitesProvider;
 import com.google.devtools.build.lib.analysis.FileProvider;
-import com.google.devtools.build.lib.analysis.FilesToCompileProvider;
 import com.google.devtools.build.lib.analysis.LanguageDependentFragment;
 import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
 import com.google.devtools.build.lib.analysis.RuleContext;
 import com.google.devtools.build.lib.analysis.Runfiles;
 import com.google.devtools.build.lib.analysis.RunfilesProvider;
 import com.google.devtools.build.lib.analysis.TempsProvider;
+import com.google.devtools.build.lib.analysis.TopLevelArtifactProvider;
 import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
@@ -48,12 +48,12 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 import java.util.regex.Pattern;
 
 import javax.annotation.Nullable;
@@ -85,17 +85,21 @@
    * context.
    */
   public static final class Info {
-    private final Map<Class<? extends TransitiveInfoProvider>, TransitiveInfoProvider> providers;
+    private final ImmutableMap<Class<? extends TransitiveInfoProvider>, TransitiveInfoProvider>
+        providers;
+    private final ImmutableMap<String, NestedSet<Artifact>> outputGroups;
     private final CcCompilationOutputs compilationOutputs;
     private final CcLinkingOutputs linkingOutputs;
     private final CcLinkingOutputs linkingOutputsExcludingPrecompiledLibraries;
     private final CppCompilationContext context;
 
     private Info(Map<Class<? extends TransitiveInfoProvider>, TransitiveInfoProvider> providers,
+        Map<String, NestedSet<Artifact>> outputGroups,
         CcCompilationOutputs compilationOutputs, CcLinkingOutputs linkingOutputs,
         CcLinkingOutputs linkingOutputsExcludingPrecompiledLibraries,
         CppCompilationContext context) {
-      this.providers = Collections.unmodifiableMap(providers);
+      this.providers = ImmutableMap.copyOf(providers);
+      this.outputGroups = ImmutableMap.copyOf(outputGroups);
       this.compilationOutputs = compilationOutputs;
       this.linkingOutputs = linkingOutputs;
       this.linkingOutputsExcludingPrecompiledLibraries =
@@ -107,6 +111,10 @@
       return providers;
     }
 
+    public ImmutableMap<String, NestedSet<Artifact>> getOutputGroups() {
+      return outputGroups;
+    }
+
     public CcCompilationOutputs getCcCompilationOutputs() {
       return compilationOutputs;
     }
@@ -538,8 +546,8 @@
   }
 
   /**
-   * Enables the output of {@link FilesToCompileProvider} and {@link
-   * CompilationPrerequisitesProvider}.
+   * Enables the output of the {@code files_to_compile} and {@code compilation_prerequisites}
+   * output groups.
    */
   // TODO(bazel-team): We probably need to adjust this for the multi-language rules.
   public CcLibraryHelper enableCompileProviders() {
@@ -642,10 +650,10 @@
         dwoArtifacts.getDwoArtifacts(), dwoArtifacts.getPicDwoArtifacts()));
     providers.put(TransitiveLipoInfoProvider.class, collectTransitiveLipoInfo(ccOutputs));
     providers.put(TempsProvider.class, getTemps(ccOutputs));
+    Map<String, NestedSet<Artifact>> outputGroups = new TreeMap<>();
     if (emitCompileProviders) {
-      providers.put(FilesToCompileProvider.class, new FilesToCompileProvider(
-          getFilesToCompile(ccOutputs)));
-      providers.put(CompilationPrerequisitesProvider.class,
+      outputGroups.put(TopLevelArtifactProvider.FILES_TO_COMPILE, getFilesToCompile(ccOutputs));
+      outputGroups.put(TopLevelArtifactProvider.COMPILATION_PREREQUISITES,
           CcCommon.collectCompilationPrerequisites(ruleContext, cppCompilationContext));
     }
 
@@ -666,7 +674,7 @@
       providers.put(CcLinkParamsProvider.class, new CcLinkParamsProvider(
           createCcLinkParamsStore(ccLinkingOutputs, cppCompilationContext, forcePic)));
     }
-    return new Info(providers, ccOutputs, ccLinkingOutputs, originalLinkingOutputs,
+    return new Info(providers, outputGroups, ccOutputs, ccLinkingOutputs, originalLinkingOutputs,
         cppCompilationContext);
   }
 
@@ -868,9 +876,10 @@
         : new TempsProvider(compilationOutputs.getTemps());
   }
 
-  private ImmutableList<Artifact> getFilesToCompile(CcCompilationOutputs compilationOutputs) {
+  private NestedSet<Artifact> getFilesToCompile(CcCompilationOutputs compilationOutputs) {
     return ruleContext.getFragment(CppConfiguration.class).isLipoContextCollector()
-        ? ImmutableList.<Artifact>of()
-        : compilationOutputs.getObjectFiles(CppHelper.usePic(ruleContext, false));
+        ? NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER)
+        : NestedSetBuilder.<Artifact>wrap(Order.STABLE_ORDER,
+            compilationOutputs.getObjectFiles(CppHelper.usePic(ruleContext, false)));
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java
index 627040d..260c41b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java
@@ -28,7 +28,6 @@
 import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
 import com.google.devtools.build.lib.analysis.AnalysisUtils;
 import com.google.devtools.build.lib.analysis.FileProvider;
-import com.google.devtools.build.lib.analysis.FilesToCompileProvider;
 import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
 import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
 import com.google.devtools.build.lib.analysis.RuleContext;
@@ -38,6 +37,7 @@
 import com.google.devtools.build.lib.analysis.Util;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.packages.TargetUtils;
 import com.google.devtools.build.lib.packages.Type;
 import com.google.devtools.build.lib.rules.cpp.CppCompilationContext;
@@ -487,9 +487,8 @@
     builder
         .add(InstrumentedFilesProvider.class, new InstrumentedFilesProviderImpl(
             instrumentedFilesCollector))
-        .add(FilesToCompileProvider.class,
-            new FilesToCompileProvider(getFilesToCompile(classJar)))
-        .add(JavaExportsProvider.class, new JavaExportsProvider(collectTransitiveExports()));
+        .add(JavaExportsProvider.class, new JavaExportsProvider(collectTransitiveExports()))
+        .addOutputGroup(TopLevelArtifactProvider.FILES_TO_COMPILE, getFilesToCompile(classJar));
 
     if (!TargetUtils.isTestRule(ruleContext.getTarget())) {
       builder.addOutputGroup(TopLevelArtifactProvider.BASELINE_COVERAGE,
@@ -607,12 +606,12 @@
         ruleContext.attributes().get("neverlink", Type.BOOLEAN);
   }
 
-  private ImmutableList<Artifact> getFilesToCompile(Artifact classJar) {
+  private NestedSet<Artifact> getFilesToCompile(Artifact classJar) {
     if (classJar == null) {
       // Some subclasses don't produce jars
-      return ImmutableList.of();
+      return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
     }
-    return ImmutableList.of(classJar);
+    return NestedSetBuilder.create(Order.STABLE_ORDER, classJar);
   }
 
   public ImmutableList<Dependency> computeStrictDepsFromJavaAttributes(