Update actions to use NestedSet for inputs (part 2; tests)

This is in preparation for making NestedSet not implement Iterable. Unfortunately, doing so means that there is no longer a common super-type for NestedSet and Collection, which means that we have to use NestedSet for all action inputs.

PiperOrigin-RevId: 284911679
diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD
index f89ce08..706db4f 100644
--- a/src/test/java/com/google/devtools/build/lib/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/BUILD
@@ -581,6 +581,7 @@
         "//src/main/java/com/google/devtools/build/lib:util",
         "//src/main/java/com/google/devtools/build/lib/actions",
         "//src/main/java/com/google/devtools/build/lib/clock",
+        "//src/main/java/com/google/devtools/build/lib/collect/nestedset",
         "//src/main/java/com/google/devtools/build/lib/concurrent",
         "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec",
         "//src/main/java/com/google/devtools/build/lib/vfs",
diff --git a/src/test/java/com/google/devtools/build/lib/actions/MapBasedActionGraphTest.java b/src/test/java/com/google/devtools/build/lib/actions/MapBasedActionGraphTest.java
index 080493c..4207588 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/MapBasedActionGraphTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/MapBasedActionGraphTest.java
@@ -20,6 +20,8 @@
 import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
 import com.google.devtools.build.lib.actions.util.ActionsTestUtil.UncheckedActionConflictException;
 import com.google.devtools.build.lib.actions.util.TestAction;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.concurrent.AbstractQueueVisitor;
 import com.google.devtools.build.lib.concurrent.ErrorClassifier;
 import com.google.devtools.build.lib.vfs.FileSystem;
@@ -48,14 +50,20 @@
     Path path = root.getRelative("foo");
     Artifact output =
         ActionsTestUtil.createArtifact(ArtifactRoot.asDerivedRoot(execRoot, root), path);
-    Action action = new TestAction(TestAction.NO_EFFECT,
-        ImmutableSet.<Artifact>of(), ImmutableSet.of(output));
+    Action action =
+        new TestAction(
+            TestAction.NO_EFFECT,
+            NestedSetBuilder.emptySet(Order.STABLE_ORDER),
+            ImmutableSet.of(output));
     actionGraph.registerAction(action);
     actionGraph.unregisterAction(action);
     path = root.getRelative("bar");
     output = ActionsTestUtil.createArtifact(ArtifactRoot.asDerivedRoot(execRoot, root), path);
-    Action action2 = new TestAction(TestAction.NO_EFFECT,
-        ImmutableSet.<Artifact>of(), ImmutableSet.of(output));
+    Action action2 =
+        new TestAction(
+            TestAction.NO_EFFECT,
+            NestedSetBuilder.emptySet(Order.STABLE_ORDER),
+            ImmutableSet.of(output));
     actionGraph.registerAction(action);
     actionGraph.registerAction(action2);
     actionGraph.unregisterAction(action);
@@ -69,11 +77,17 @@
     Path path = root.getRelative("/root/foo");
     Artifact output =
         ActionsTestUtil.createArtifact(ArtifactRoot.asDerivedRoot(execRoot, root), path);
-    Action action = new TestAction(TestAction.NO_EFFECT,
-        ImmutableSet.<Artifact>of(), ImmutableSet.of(output));
+    Action action =
+        new TestAction(
+            TestAction.NO_EFFECT,
+            NestedSetBuilder.emptySet(Order.STABLE_ORDER),
+            ImmutableSet.of(output));
     actionGraph.registerAction(action);
-    Action otherAction = new TestAction(TestAction.NO_EFFECT,
-        ImmutableSet.<Artifact>of(), ImmutableSet.of(output));
+    Action otherAction =
+        new TestAction(
+            TestAction.NO_EFFECT,
+            NestedSetBuilder.emptySet(Order.STABLE_ORDER),
+            ImmutableSet.of(output));
     actionGraph.registerAction(otherAction);
     actionGraph.unregisterAction(action);
   }
@@ -97,8 +111,11 @@
       Path root = fileSystem.getPath("/root");
       Path path = root.getRelative("foo");
       output = ActionsTestUtil.createArtifact(ArtifactRoot.asDerivedRoot(execRoot, root), path);
-      allActions.add(new TestAction(
-          TestAction.NO_EFFECT, ImmutableSet.<Artifact>of(), ImmutableSet.of(output)));
+      allActions.add(
+          new TestAction(
+              TestAction.NO_EFFECT,
+              NestedSetBuilder.emptySet(Order.STABLE_ORDER),
+              ImmutableSet.of(output)));
     }
 
     private void registerAction(final Action action) {
@@ -135,8 +152,11 @@
       if (Math.random() < 0.5) {
         action = Iterables.getFirst(allActions, null);
       } else {
-        action = new TestAction(
-            TestAction.NO_EFFECT, ImmutableSet.<Artifact>of(), ImmutableSet.of(output));
+        action =
+            new TestAction(
+                TestAction.NO_EFFECT,
+                NestedSetBuilder.emptySet(Order.STABLE_ORDER),
+                ImmutableSet.of(output));
         allActions.add(action);
       }
       if (Math.random() < 0.5) {
diff --git a/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java b/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java
index 869549c..5ba5c96 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java
@@ -63,6 +63,8 @@
 import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.cmdline.RepositoryName;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.events.EventHandler;
 import com.google.devtools.build.lib.events.ExtendedEventHandler;
 import com.google.devtools.build.lib.events.Reporter;
@@ -365,19 +367,28 @@
   public static class NullAction extends AbstractAction {
 
     public NullAction() {
-      super(NULL_ACTION_OWNER, Artifact.NO_ARTIFACTS, ImmutableList.of(DUMMY_ARTIFACT));
+      super(
+          NULL_ACTION_OWNER,
+          NestedSetBuilder.emptySet(Order.STABLE_ORDER),
+          ImmutableList.of(DUMMY_ARTIFACT));
     }
 
     public NullAction(ActionOwner owner, Artifact... outputs) {
-      super(owner, Artifact.NO_ARTIFACTS, ImmutableList.copyOf(outputs));
+      super(owner, NestedSetBuilder.emptySet(Order.STABLE_ORDER), ImmutableList.copyOf(outputs));
     }
 
     public NullAction(Artifact... outputs) {
-      super(NULL_ACTION_OWNER, Artifact.NO_ARTIFACTS, ImmutableList.copyOf(outputs));
+      super(
+          NULL_ACTION_OWNER,
+          NestedSetBuilder.emptySet(Order.STABLE_ORDER),
+          ImmutableList.copyOf(outputs));
     }
 
     public NullAction(List<Artifact> inputs, Artifact... outputs) {
-      super(NULL_ACTION_OWNER, inputs, ImmutableList.copyOf(outputs));
+      super(
+          NULL_ACTION_OWNER,
+          NestedSetBuilder.wrap(Order.STABLE_ORDER, inputs),
+          ImmutableList.copyOf(outputs));
     }
 
     @Override
diff --git a/src/test/java/com/google/devtools/build/lib/actions/util/TestAction.java b/src/test/java/com/google/devtools/build/lib/actions/util/TestAction.java
index c87a7a1..15c0251 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/util/TestAction.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/util/TestAction.java
@@ -17,18 +17,22 @@
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.actions.AbstractAction;
+import com.google.devtools.build.lib.actions.ActionAnalysisMetadata.MiddlemanType;
 import com.google.devtools.build.lib.actions.ActionExecutionContext;
 import com.google.devtools.build.lib.actions.ActionExecutionException;
 import com.google.devtools.build.lib.actions.ActionKeyContext;
 import com.google.devtools.build.lib.actions.ActionResult;
 import com.google.devtools.build.lib.actions.Artifact;
+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.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.util.Fingerprint;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
 import java.io.IOException;
-import java.util.Collection;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Executors;
 
@@ -46,45 +50,44 @@
         public void run() {}
       };
 
+  private static boolean isOptional(Artifact artifact) {
+    return artifact.getExecPath().getBaseName().endsWith(".optional");
+  }
+
+  private static ImmutableList<Artifact> mandatoryArtifacts(Iterable<Artifact> inputs) {
+    return ImmutableList.copyOf(Iterables.filter(inputs, a -> !isOptional(a)));
+  }
+
+  private static ImmutableList<Artifact> optionalArtifacts(Iterable<Artifact> inputs) {
+    return ImmutableList.copyOf(Iterables.filter(inputs, a -> isOptional(a)));
+  }
+
   protected final Callable<Void> effect;
   private final ImmutableList<Artifact> mandatoryInputs;
   private final ImmutableList<Artifact> optionalInputs;
 
   /** Use this constructor if the effect can't throw exceptions. */
-  public TestAction(Runnable effect,
-             Collection<Artifact> inputs,
-             Collection<Artifact> outputs) {
+  public TestAction(Runnable effect, NestedSet<Artifact> inputs, ImmutableSet<Artifact> outputs) {
     this(Executors.callable(effect, null), inputs, outputs);
   }
 
-  private static boolean isOptional(Artifact artifact) {
-    return artifact.getExecPath().getBaseName().endsWith(".optional");
-  }
-
-  private static ImmutableList<Artifact> mandatoryArtifacts(Collection<Artifact> inputs) {
-    return inputs.stream().filter(a -> !isOptional(a)).collect(ImmutableList.toImmutableList());
-  }
-
-  private static ImmutableList<Artifact> optionalArtifacts(Collection<Artifact> inputs) {
-    return inputs.stream().filter(a -> isOptional(a)).collect(ImmutableList.toImmutableList());
-  }
-
   /**
-   * Use this constructor if the effect can throw exceptions.
-   * Any checked exception thrown will be repackaged as an
-   * ActionExecutionException.
+   * Use this constructor if the effect can throw exceptions. Any checked exception thrown will be
+   * repackaged as an ActionExecutionException.
    */
-  public TestAction(Callable<Void> effect,
-             Collection<Artifact> inputs,
-             Collection<Artifact> outputs) {
-    super(NULL_ACTION_OWNER, mandatoryArtifacts(inputs), outputs);
+  public TestAction(
+      Callable<Void> effect, NestedSet<Artifact> inputs, ImmutableSet<Artifact> outputs) {
+    super(
+        NULL_ACTION_OWNER,
+        NestedSetBuilder.wrap(Order.STABLE_ORDER, mandatoryArtifacts(inputs)),
+        outputs);
     this.mandatoryInputs = mandatoryArtifacts(inputs);
     this.optionalInputs = optionalArtifacts(inputs);
     this.effect = effect;
   }
 
   @Override
-  public Collection<Artifact> getMandatoryInputs() {
+  public Iterable<Artifact> getMandatoryInputs() {
     return mandatoryInputs;
   }
 
@@ -155,12 +158,12 @@
     private final MiddlemanType type;
 
     @AutoCodec.Instantiator
-    public DummyAction(Collection<Artifact> inputs, Artifact primaryOutput, MiddlemanType type) {
-      super(NO_EFFECT, inputs, ImmutableList.of(primaryOutput));
+    public DummyAction(NestedSet<Artifact> inputs, Artifact primaryOutput, MiddlemanType type) {
+      super(NO_EFFECT, inputs, ImmutableSet.of(primaryOutput));
       this.type = type;
     }
 
-    public DummyAction(Collection<Artifact> inputs, Artifact output) {
+    public DummyAction(NestedSet<Artifact> inputs, Artifact output) {
       this(inputs, output, MiddlemanType.NORMAL);
     }
 
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTest.java
index 7effb91..ef150b3 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTest.java
@@ -39,6 +39,8 @@
 import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
 import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
 import com.google.devtools.build.lib.actions.util.TestAction.DummyAction;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.events.NullEventHandler;
 import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester;
 import com.google.devtools.build.lib.util.Pair;
@@ -137,7 +139,9 @@
     file(treeFile2.getPath(), "src2");
     Action action =
         new DummyAction(
-            ImmutableList.of(input1, input2, tree), output, MiddlemanType.AGGREGATING_MIDDLEMAN);
+            NestedSetBuilder.create(Order.STABLE_ORDER, input1, input2, tree),
+            output,
+            MiddlemanType.AGGREGATING_MIDDLEMAN);
     actions.add(action);
     file(input2.getPath(), "contents");
     file(input1.getPath(), "source contents");
@@ -311,7 +315,7 @@
     Artifact.DerivedArtifact output =
         new Artifact.DerivedArtifact(
             ArtifactRoot.asDerivedRoot(root, root.getRelative("out")), execPath, ALL_OWNER);
-    actions.add(new DummyAction(ImmutableList.<Artifact>of(), output));
+    actions.add(new DummyAction(NestedSetBuilder.emptySet(Order.STABLE_ORDER), output));
     output.setGeneratingActionKey(ActionLookupData.create(ALL_OWNER, actions.size() - 1));
     return output;
   }
@@ -325,7 +329,7 @@
 
   private SpecialArtifact createDerivedTreeArtifactWithAction(String path) {
     SpecialArtifact treeArtifact = createDerivedTreeArtifactOnly(path);
-    actions.add(new DummyAction(ImmutableList.<Artifact>of(), treeArtifact));
+    actions.add(new DummyAction(NestedSetBuilder.emptySet(Order.STABLE_ORDER), treeArtifact));
     return treeArtifact;
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FilesystemValueCheckerTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FilesystemValueCheckerTest.java
index a823807..3814bff 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/FilesystemValueCheckerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/FilesystemValueCheckerTest.java
@@ -41,6 +41,8 @@
 import com.google.devtools.build.lib.analysis.ServerDirectories;
 import com.google.devtools.build.lib.clock.BlazeClock;
 import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.events.NullEventHandler;
 import com.google.devtools.build.lib.packages.WorkspaceFileValue;
 import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
@@ -414,12 +416,14 @@
             actionKey1,
                 actionValue(
                     new TestAction(
-                        Runnables.doNothing(), ImmutableSet.<Artifact>of(), ImmutableSet.of(out1))),
+                        Runnables.doNothing(),
+                        NestedSetBuilder.emptySet(Order.STABLE_ORDER),
+                        ImmutableSet.of(out1))),
             actionKey2,
                 actionValue(
                     new TestAction(
                         Runnables.doNothing(),
-                        ImmutableSet.<Artifact>of(),
+                        NestedSetBuilder.emptySet(Order.STABLE_ORDER),
                         ImmutableSet.of(out2)))));
     assertThat(driver.evaluate(ImmutableList.<SkyKey>of(), evaluationContext).hasError()).isFalse();
     assertThat(
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ParallelBuilderTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ParallelBuilderTest.java
index 52a8eef..9db32b2 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/ParallelBuilderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/ParallelBuilderTest.java
@@ -19,7 +19,6 @@
 import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;
 import static org.junit.Assert.fail;
 
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
@@ -34,6 +33,9 @@
 import com.google.devtools.build.lib.actions.BuildFailedException;
 import com.google.devtools.build.lib.actions.cache.ActionCache;
 import com.google.devtools.build.lib.actions.util.TestAction;
+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.events.Event;
 import com.google.devtools.build.lib.events.EventHandler;
 import com.google.devtools.build.lib.events.EventKind;
@@ -89,6 +91,11 @@
     return Sets.newHashSet(elements);
   }
 
+  @SafeVarargs
+  protected static <T> NestedSet<T> asNestedSet(T... elements) {
+    return NestedSetBuilder.create(Order.STABLE_ORDER, elements);
+  }
+
   protected void buildArtifacts(Artifact... artifacts) throws Exception {
     buildArtifacts(createBuilder(DEFAULT_NUM_JOBS, false), artifacts);
   }
@@ -141,7 +148,7 @@
             fail("ParallelBuilderTest: foo: waiting for bar: timed out");
           }
         };
-    registerAction(new TestAction(makeFoo, Artifact.NO_ARTIFACTS, ImmutableList.of(foo)));
+    registerAction(new TestAction(makeFoo, emptyNestedSet, ImmutableSet.of(foo)));
 
     // [action] -> bar
     Artifact bar = createDerivedArtifact("bar");
@@ -163,7 +170,7 @@
             fail("ParallelBuilderTest: bar: waiting for foo: timed out");
           }
         };
-    registerAction(new TestAction(makeBar, Artifact.NO_ARTIFACTS, ImmutableList.of(bar)));
+    registerAction(new TestAction(makeBar, emptyNestedSet, ImmutableSet.of(bar)));
 
     buildArtifacts(builder, foo, bar);
   }
@@ -187,7 +194,9 @@
     ActionEventRecorder recorder = new ActionEventRecorder();
     eventBus.register(recorder);
 
-    Action action = registerAction(new TestAction(Runnables.doNothing(), emptySet, asSet(pear)));
+    Action action =
+        registerAction(
+            new TestAction(Runnables.doNothing(), emptyNestedSet, ImmutableSet.of(pear)));
 
     buildArtifacts(createBuilder(DEFAULT_NUM_JOBS, true), pear);
     assertThat(recorder.actionExecutedEvents).hasSize(1);
@@ -213,11 +222,11 @@
             throw new IOException("building 'foo' is supposed to fail");
           }
         };
-    registerAction(new TestAction(makeFoo, Artifact.NO_ARTIFACTS, ImmutableList.of(foo)));
+    registerAction(new TestAction(makeFoo, emptyNestedSet, ImmutableSet.of(foo)));
 
     // [action] -> bar
     Artifact bar = createDerivedArtifact("bar");
-    registerAction(new TestAction(TestAction.NO_EFFECT, emptySet, ImmutableList.of(bar)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, emptyNestedSet, ImmutableSet.of(bar)));
 
     // Don't fail fast when we encounter the error
     reporter.removeHandler(failFastHandler);
@@ -288,7 +297,7 @@
       }
     };
     Artifact foo = createDerivedArtifact(fs, "foo");
-    registerAction(new TestAction(TestAction.NO_EFFECT, emptySet, ImmutableList.of(foo)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, emptyNestedSet, ImmutableSet.of(foo)));
     reporter.removeHandler(failFastHandler);
     assertThrows(BuildFailedException.class, () -> buildArtifacts(foo));
     assertContainsEvent("not all outputs were created or valid");
@@ -383,7 +392,7 @@
           numOutputs = artifacts.length - i;
         }
 
-        Collection<Artifact> inputs = new ArrayList<>(numInputs);
+        NestedSetBuilder<Artifact> inputs = NestedSetBuilder.stableOrder();
         for (int j = 0; j < numInputs; j++) {
           if (i != 0) {
             int inputNum = random.nextInt(i);
@@ -394,7 +403,7 @@
         for (int j = 0; j < numOutputs; j++) {
           outputs.add(artifacts[i + j]);
         }
-        counters.add(createActionCounter(inputs, outputs));
+        counters.add(createActionCounter(inputs.build(), ImmutableSet.copyOf(outputs)));
         if (inputs.isEmpty()) {
           // source files -- create them
           for (Artifact output : outputs) {
@@ -516,7 +525,7 @@
             throw new IOException("foo action failed");
           }
         };
-    registerAction(new TestAction(makeFoo, Artifact.NO_ARTIFACTS, ImmutableList.of(foo)));
+    registerAction(new TestAction(makeFoo, emptyNestedSet, ImmutableSet.of(foo)));
 
     // [action] -> bar
     Artifact bar = createDerivedArtifact("bar");
@@ -534,7 +543,7 @@
             finished[0] = true;
           }
         };
-    registerAction(new TestAction(makeBar, emptySet, asSet(bar)));
+    registerAction(new TestAction(makeBar, emptyNestedSet, ImmutableSet.of(bar)));
 
     // Don't fail fast when we encounter the error
     reporter.removeHandler(failFastHandler);
@@ -559,9 +568,9 @@
     Artifact foo = createDerivedArtifact("foo");
     Artifact bar = createDerivedArtifact("bar");
     Artifact baz = createDerivedArtifact("baz");
-    registerAction(new TestAction(TestAction.NO_EFFECT, asSet(foo), asSet(bar)));
-    registerAction(new TestAction(TestAction.NO_EFFECT, asSet(bar), asSet(baz)));
-    registerAction(new TestAction(TestAction.NO_EFFECT, asSet(baz), asSet(foo)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, asNestedSet(foo), ImmutableSet.of(bar)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, asNestedSet(bar), ImmutableSet.of(baz)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, asNestedSet(baz), ImmutableSet.of(foo)));
     BuildFailedException e =
         assertThrows(
             "Builder failed to detect cyclic action graph",
@@ -574,7 +583,7 @@
   public void testSelfCyclicActionGraph() throws Exception {
     // foo -> [action] -> foo
     Artifact foo = createDerivedArtifact("foo");
-    registerAction(new TestAction(TestAction.NO_EFFECT, asSet(foo), asSet(foo)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, asNestedSet(foo), ImmutableSet.of(foo)));
     BuildFailedException e =
         assertThrows(
             "Builder failed to detect cyclic action graph",
@@ -593,10 +602,10 @@
     Artifact foo2 = createDerivedArtifact("foo2");
     Artifact bar = createDerivedArtifact("bar");
     Artifact baz = createDerivedArtifact("baz");
-    registerAction(new TestAction(TestAction.NO_EFFECT, asSet(bar), asSet(foo1)));
-    registerAction(new TestAction(TestAction.NO_EFFECT, asSet(bar), asSet(foo2)));
-    registerAction(new TestAction(TestAction.NO_EFFECT, asSet(baz), asSet(bar)));
-    registerAction(new TestAction(TestAction.NO_EFFECT, asSet(bar), asSet(baz)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, asNestedSet(bar), ImmutableSet.of(foo1)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, asNestedSet(bar), ImmutableSet.of(foo2)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, asNestedSet(baz), ImmutableSet.of(bar)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, asNestedSet(bar), ImmutableSet.of(baz)));
     BuildFailedException e =
         assertThrows(
             "Builder failed to detect cyclic action graph",
@@ -615,10 +624,11 @@
     Artifact bar = createDerivedArtifact("bar");
     Artifact baz = createDerivedArtifact("baz");
     Artifact bat = createDerivedArtifact("bat");
-    registerAction(new TestAction(TestAction.NO_EFFECT, asSet(bar), asSet(foo)));
-    registerAction(new TestAction(TestAction.NO_EFFECT, asSet(baz), asSet(bar)));
-    registerAction(new TestAction(TestAction.NO_EFFECT, asSet(bat, foo), asSet(baz)));
-    registerAction(new TestAction(TestAction.NO_EFFECT, ImmutableSet.<Artifact>of(), asSet(bat)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, asNestedSet(bar), ImmutableSet.of(foo)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, asNestedSet(baz), ImmutableSet.of(bar)));
+    registerAction(
+        new TestAction(TestAction.NO_EFFECT, asNestedSet(bat, foo), ImmutableSet.of(baz)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, emptyNestedSet, ImmutableSet.of(bat)));
     BuildFailedException e =
         assertThrows(
             "Builder failed to detect cyclic action graph",
@@ -633,10 +643,9 @@
     // (foo, foo) -> [action] -> bar
     Artifact foo = createDerivedArtifact("foo");
     Artifact bar = createDerivedArtifact("bar");
+    registerAction(new TestAction(TestAction.NO_EFFECT, emptyNestedSet, ImmutableSet.of(foo)));
     registerAction(
-        new TestAction(TestAction.NO_EFFECT, ParallelBuilderTest.<Artifact>asSet(), asSet(foo)));
-    registerAction(
-        new TestAction(TestAction.NO_EFFECT, Lists.<Artifact>newArrayList(foo, foo), asSet(bar)));
+        new TestAction(TestAction.NO_EFFECT, asNestedSet(foo, foo), ImmutableSet.of(bar)));
     buildArtifacts(bar);
   }
 
@@ -663,9 +672,8 @@
 
     for (int ii = 0; ii < numJobs; ++ii) {
       Artifact out = createDerivedArtifact(ii + ".out");
-      List<Artifact> inputs = (catastrophe && ii > 10)
-          ? ImmutableList.of(artifacts[0])
-          : Artifact.NO_ARTIFACTS;
+      NestedSet<Artifact> inputs =
+          (catastrophe && ii > 10) ? asNestedSet(artifacts[0]) : emptyNestedSet;
       final int iCopy = ii;
       registerAction(
           new TestAction(
@@ -678,7 +686,7 @@
                 }
               },
               inputs,
-              ImmutableList.of(out)) {
+              ImmutableSet.of(out)) {
             @Override
             public ActionResult execute(ActionExecutionContext actionExecutionContext)
                 throws ActionExecutionException {
@@ -731,7 +739,7 @@
     // Build three artifacts in 3 separate actions (baz depends on bar and bar
     // depends on foo.  Make sure progress is reported at the beginning of all
     // three actions.
-    List<Artifact> sourceFiles = new ArrayList<>();
+    NestedSetBuilder<Artifact> sourceFiles = NestedSetBuilder.stableOrder();
     for (int i = 0; i < 10; i++) {
       sourceFiles.add(createInputFile("file" + i));
     }
@@ -758,9 +766,9 @@
     reporter.addHandler(handler);
     reporter.addHandler(new PrintingEventHandler(EventKind.ALL_EVENTS));
 
-    registerAction(new TestAction(TestAction.NO_EFFECT, sourceFiles, asSet(foo)));
-    registerAction(new TestAction(TestAction.NO_EFFECT, asSet(foo), asSet(bar)));
-    registerAction(new TestAction(TestAction.NO_EFFECT, asSet(bar), asSet(baz)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, sourceFiles.build(), ImmutableSet.of(foo)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, asNestedSet(foo), ImmutableSet.of(bar)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, asNestedSet(bar), ImmutableSet.of(baz)));
     buildArtifacts(baz);
     // Check that the percentages increase non-linearly, because foo has 10 input files
     List<String> expectedMessages = Lists.newArrayList(
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java
index a9c3b74..80f600a 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java
@@ -34,6 +34,8 @@
 import com.google.devtools.build.lib.actions.FileStateValue;
 import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
 import com.google.devtools.build.lib.actions.util.DummyExecutor;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.testutil.TimestampGranularityUtils;
 import com.google.devtools.build.lib.util.Fingerprint;
 import com.google.devtools.build.lib.vfs.Path;
@@ -181,7 +183,10 @@
     private final AtomicInteger executionCounter;
 
     ExecutionCountingAction(Artifact input, Artifact output, AtomicInteger executionCounter) {
-      super(ActionsTestUtil.NULL_ACTION_OWNER, ImmutableList.of(input), ImmutableList.of(output));
+      super(
+          ActionsTestUtil.NULL_ACTION_OWNER,
+          NestedSetBuilder.create(Order.STABLE_ORDER, input),
+          ImmutableSet.of(output));
       this.executionCounter = executionCounter;
     }
 
@@ -668,8 +673,10 @@
     SingleOutputAction(@Nullable Artifact input, Artifact output) {
       super(
           ActionsTestUtil.NULL_ACTION_OWNER,
-          input == null ? ImmutableList.<Artifact>of() : ImmutableList.of(input),
-          ImmutableList.of(output));
+          input == null
+              ? NestedSetBuilder.emptySet(Order.STABLE_ORDER)
+              : NestedSetBuilder.create(Order.STABLE_ORDER, input),
+          ImmutableSet.of(output));
     }
 
     protected static final class Buffer {
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderMediumTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderMediumTest.java
index fcc784b..419c2a6 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderMediumTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderMediumTest.java
@@ -16,12 +16,13 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;
 
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.cache.CompactPersistentActionCache;
+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.testutil.BlazeTestUtils;
 import com.google.devtools.build.lib.testutil.Suite;
 import com.google.devtools.build.lib.testutil.TestSpec;
@@ -56,6 +57,10 @@
     return new CompactPersistentActionCache(cacheRoot, clock);
   }
 
+  private static NestedSet<Artifact> asNestedSet(Artifact... artifacts) {
+    return NestedSetBuilder.create(Order.STABLE_ORDER, artifacts);
+  }
+
   /**
    * Creates and returns a new caching builder based on a given {@code cache}.
    */
@@ -74,7 +79,7 @@
     FileSystemUtils.writeContentAsLatin1(hello.getPath(), "content1");
     Artifact optional = createSourceArtifact("hello.optional");
     Artifact goodbye = createDerivedArtifact("goodbye");
-    Button button = createActionButton(Sets.newHashSet(hello, optional), Sets.newHashSet(goodbye));
+    Button button = createActionButton(asNestedSet(hello, optional), ImmutableSet.of(goodbye));
 
     button.pressed = false;
     buildArtifacts(persistentBuilder(cache), goodbye);
@@ -123,7 +128,7 @@
     Artifact hello = createSourceArtifact("hello");
     BlazeTestUtils.makeEmptyFile(hello.getPath());
     Artifact goodbye = createDerivedArtifact("goodbye");
-    Button button = createActionButton(Sets.newHashSet(hello), Sets.newHashSet(goodbye));
+    Button button = createActionButton(asNestedSet(hello), ImmutableSet.of(goodbye));
 
     button.pressed = false;
     buildArtifacts(persistentBuilder(cache), goodbye);
@@ -157,7 +162,7 @@
     FileSystemUtils.createDirectoryAndParents(hello.getPath().getParentDirectory());
     FileSystemUtils.writeContentAsLatin1(hello.getPath(), "content1");
     Artifact goodbye = createDerivedArtifact("goodbye");
-    Button button = createActionButton(Sets.newHashSet(hello), Sets.newHashSet(goodbye));
+    Button button = createActionButton(asNestedSet(hello), ImmutableSet.of(goodbye));
 
     button.pressed = false;
     buildArtifacts(persistentBuilder(cache), goodbye);
@@ -197,9 +202,7 @@
     FileSystemUtils.writeContentAsLatin1(hello.getPath(), "hello");
     FileSystemUtils.writeContentAsLatin1(there.getPath(), "there");
     Artifact goodbye = createDerivedArtifact("goodbye");
-    Button button =
-        createActionButton(
-            Sets.newLinkedHashSet(ImmutableList.of(hello, there)), Sets.newHashSet(goodbye));
+    Button button = createActionButton(asNestedSet(hello, there), ImmutableSet.of(goodbye));
 
     button.pressed = false;
     buildArtifacts(persistentBuilder(cache), goodbye);
@@ -212,9 +215,7 @@
     // Now create duplicate graph, with swapped order.
     clearActions();
     Artifact goodbye2 = createDerivedArtifact("goodbye");
-    Button button2 =
-        createActionButton(
-            Sets.newLinkedHashSet(ImmutableList.of(there, hello)), Sets.newHashSet(goodbye2));
+    Button button2 = createActionButton(asNestedSet(there, hello), ImmutableSet.of(goodbye2));
 
     button2.pressed = false;
     buildArtifacts(persistentBuilder(cache), goodbye);
@@ -227,7 +228,7 @@
     Artifact goodbye = createDerivedArtifact("goodbye");
     FileSystemUtils.createDirectoryAndParents(goodbye.getPath().getParentDirectory());
     FileSystemUtils.writeContentAsLatin1(goodbye.getPath(), "test");
-    Button button = createActionButton(emptySet, Sets.newLinkedHashSet(ImmutableList.of(goodbye)));
+    Button button = createActionButton(emptyNestedSet, ImmutableSet.of(goodbye));
 
     button.pressed = false;
     buildArtifacts(persistentBuilder(cache), goodbye);
@@ -240,8 +241,7 @@
     clearActions();
     Artifact hello = createDerivedArtifact("hello");
     Artifact goodbye2 = createDerivedArtifact("goodbye");
-    Button button2 =
-        createActionButton(emptySet, Sets.newLinkedHashSet(ImmutableList.of(hello, goodbye2)));
+    Button button2 = createActionButton(emptyNestedSet, ImmutableSet.of(hello, goodbye2));
 
     button2.pressed = false;
     buildArtifacts(persistentBuilder(cache), hello, goodbye2);
@@ -262,7 +262,7 @@
     FileSystemUtils.createDirectoryAndParents(hello.getPath().getParentDirectory());
     FileSystemUtils.writeContentAsLatin1(hello.getPath(), "hello");
     Artifact goodbye = createDerivedArtifact("goodbye");
-    Button button = createActionButton(Sets.newHashSet(hello), Sets.newHashSet(goodbye));
+    Button button = createActionButton(asNestedSet(hello), ImmutableSet.of(goodbye));
 
     button.pressed = false;
     buildArtifacts(persistentBuilder(cache), goodbye);
@@ -278,7 +278,7 @@
     FileSystemUtils.createDirectoryAndParents(hi.getPath().getParentDirectory());
     FileSystemUtils.writeContentAsLatin1(hi.getPath(), "hello");
     Artifact goodbye2 = createDerivedArtifact("goodbye");
-    Button button2 = createActionButton(Sets.newHashSet(hi), Sets.newHashSet(goodbye2));
+    Button button2 = createActionButton(asNestedSet(hi), ImmutableSet.of(goodbye2));
 
     button2.pressed = false;
     buildArtifacts(persistentBuilder(cache), goodbye2);
@@ -293,8 +293,7 @@
     FileSystemUtils.createDirectoryAndParents(hello.getPath().getParentDirectory());
     FileSystemUtils.writeContentAsLatin1(hello.getPath(), "hello");
     Artifact goodbye = createDerivedArtifact("goodbye");
-    Button button =
-        createActionButton(Lists.<Artifact>newArrayList(hello, hello), Sets.newHashSet(goodbye));
+    Button button = createActionButton(asNestedSet(hello, hello), ImmutableSet.of(goodbye));
 
     button.pressed = false;
     buildArtifacts(persistentBuilder(cache), goodbye);
@@ -332,7 +331,7 @@
     FileSystemUtils.createDirectoryAndParents(hello.getPath().getParentDirectory());
     FileSystemUtils.writeContentAsLatin1(hello.getPath(), "content1");
     Artifact goodbye = createDerivedArtifact("goodbye");
-    Button button = createActionButton(Sets.newHashSet(hello), Sets.newHashSet(goodbye));
+    Button button = createActionButton(asNestedSet(hello), ImmutableSet.of(goodbye));
 
     button.pressed = false;
     buildArtifacts(persistentBuilder(cache), goodbye);
@@ -354,7 +353,7 @@
   public void testPersistentCache_ModifyingOutputCausesActionReexecution() throws Exception {
     // [action] -> /hello
     Artifact hello = createDerivedArtifact("hello");
-    Button button = createActionButton(emptySet, Sets.newHashSet(hello));
+    Button button = createActionButton(emptyNestedSet, ImmutableSet.of(hello));
 
     button.pressed = false;
     buildArtifacts(persistentBuilder(cache), hello);
@@ -385,7 +384,7 @@
   public void testPersistentCache_missingFilenameIndexCausesActionReexecution() throws Exception {
     // [action] -> /hello
     Artifact hello = createDerivedArtifact("hello");
-    Button button = createActionButton(emptySet, Sets.newHashSet(hello));
+    Button button = createActionButton(emptyNestedSet, ImmutableSet.of(hello));
 
     button.pressed = false;
     buildArtifacts(persistentBuilder(cache), hello);
@@ -431,7 +430,7 @@
   public void testPersistentCache_failedIntegrityCheckCausesActionReexecution() throws Exception {
     // [action] -> /hello
     Artifact hello = createDerivedArtifact("hello");
-    Button button = createActionButton(emptySet, Sets.newHashSet(hello));
+    Button button = createActionButton(emptyNestedSet, ImmutableSet.of(hello));
 
     button.pressed = false;
     buildArtifacts(persistentBuilder(cache), hello);
@@ -463,7 +462,7 @@
 
     // Add extra records to the action cache and indexer.
     Artifact helloExtra = createDerivedArtifact("hello_extra");
-    Button buttonExtra = createActionButton(emptySet, Sets.newHashSet(helloExtra));
+    Button buttonExtra = createActionButton(emptyNestedSet, ImmutableSet.of(helloExtra));
     buildArtifacts(persistentBuilder(cache), helloExtra);
     assertThat(buttonExtra.pressed).isTrue(); // built
 
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTest.java
index 6063c0c..b090c21 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTest.java
@@ -17,14 +17,15 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;
 
-import com.google.common.collect.Sets;
+import com.google.common.collect.ImmutableSet;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.BuildFailedException;
 import com.google.devtools.build.lib.actions.util.TestAction;
+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.testutil.BlazeTestUtils;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
-import java.util.Collection;
-import java.util.Collections;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -35,12 +36,15 @@
  */
 @RunWith(JUnit4.class)
 public class TimestampBuilderTest extends TimestampBuilderTestCase {
+  private static NestedSet<Artifact> asNestedSet(Artifact... artifacts) {
+    return NestedSetBuilder.create(Order.STABLE_ORDER, artifacts);
+  }
 
   @Test
   public void testAmnesiacBuilderAlwaysRebuilds() throws Exception {
     // [action] -> hello
     Artifact hello = createDerivedArtifact("hello");
-    Button button = createActionButton(emptySet, Sets.newHashSet(hello));
+    Button button = createActionButton(emptyNestedSet, ImmutableSet.of(hello));
 
     button.pressed = false;
     buildArtifacts(amnesiacBuilder(), hello);
@@ -62,7 +66,7 @@
   public void testBuilderDoesntRevisitActions() throws Exception {
     // [action] -> hello
     Artifact hello = createDerivedArtifact("hello");
-    Counter counter = createActionCounter(emptySet, Sets.newHashSet(hello));
+    Counter counter = createActionCounter(emptyNestedSet, ImmutableSet.of(hello));
 
     Builder amnesiacBuilder = amnesiacBuilder();
 
@@ -82,7 +86,7 @@
   public void testCachingBuilderCachesUntilReset() throws Exception {
     // [action] -> hello
     Artifact hello = createDerivedArtifact("hello");
-    Button button = createActionButton(emptySet, Sets.newHashSet(hello));
+    Button button = createActionButton(emptyNestedSet, ImmutableSet.of(hello));
 
     button.pressed = false;
     buildArtifacts(cachingBuilder(), hello);
@@ -106,7 +110,7 @@
     FileSystemUtils.writeContentAsLatin1(hello.getPath(), "content1");
     Artifact optional = createSourceArtifact("hello.optional");
     Artifact goodbye = createDerivedArtifact("goodbye");
-    Button button = createActionButton(Sets.newHashSet(hello, optional), Sets.newHashSet(goodbye));
+    Button button = createActionButton(asNestedSet(hello, optional), ImmutableSet.of(goodbye));
 
     button.pressed = false;
     buildArtifacts(cachingBuilder(), goodbye);
@@ -145,7 +149,7 @@
     Artifact hello = createSourceArtifact("hello");
     BlazeTestUtils.makeEmptyFile(hello.getPath());
     Artifact goodbye = createDerivedArtifact("goodbye");
-    Button button = createActionButton(Sets.newHashSet(hello), Sets.newHashSet(goodbye));
+    Button button = createActionButton(asNestedSet(hello), ImmutableSet.of(goodbye));
 
     button.pressed = false;
     buildArtifacts(cachingBuilder(), goodbye);
@@ -176,7 +180,7 @@
     FileSystemUtils.writeContentAsLatin1(hello.getPath(), "content1");
 
     Artifact goodbye = createDerivedArtifact("goodbye");
-    Button button = createActionButton(Sets.newHashSet(hello), Sets.newHashSet(goodbye));
+    Button button = createActionButton(asNestedSet(hello), ImmutableSet.of(goodbye));
 
     button.pressed = false;
     buildArtifacts(cachingBuilder(), goodbye);
@@ -207,7 +211,7 @@
   public void testModifyingOutputCausesActionReexecution() throws Exception {
     // [action] -> hello
     Artifact hello = createDerivedArtifact("hello");
-    Button button = createActionButton(emptySet, Sets.newHashSet(hello));
+    Button button = createActionButton(emptyNestedSet, ImmutableSet.of(hello));
 
     button.pressed = false;
     buildArtifacts(cachingBuilder(), hello);
@@ -240,7 +244,7 @@
     Button button1 = new Button();
     registerAction(new CopyingAction(button1, hello, wazuup));
     Artifact goodbye = createDerivedArtifact("goodbye");
-    Button button2 = createActionButton(Sets.newHashSet(wazuup), Sets.newHashSet(goodbye));
+    Button button2 = createActionButton(asNestedSet(wazuup), ImmutableSet.of(goodbye));
 
     button1.pressed = button2.pressed = false;
     buildArtifacts(cachingBuilder(), wazuup);
@@ -277,11 +281,9 @@
 
     Artifact anOutputFile = createDerivedArtifact("anOutputFile");
     Artifact anotherOutputFile = createDerivedArtifact("anotherOutputFile");
-    Collection<Artifact> noInputs = Collections.emptySet();
 
-    Button aButton = createActionButton(noInputs, Sets.newHashSet(anOutputFile));
-    Button anotherButton = createActionButton(noInputs,
-                                              Sets.newHashSet(anotherOutputFile));
+    Button aButton = createActionButton(emptyNestedSet, ImmutableSet.of(anOutputFile));
+    Button anotherButton = createActionButton(emptyNestedSet, ImmutableSet.of(anotherOutputFile));
 
     buildArtifacts(cachingBuilder(), anOutputFile, anotherOutputFile);
 
@@ -312,8 +314,7 @@
     Artifact in = createSourceArtifact("in"); // doesn't exist
     Artifact out = createDerivedArtifact("out");
 
-    registerAction(new TestAction(TestAction.NO_EFFECT, Collections.singleton(in),
-        Collections.singleton(out)));
+    registerAction(new TestAction(TestAction.NO_EFFECT, asNestedSet(in), ImmutableSet.of(out)));
 
     BuildFailedException e =
         assertThrows(BuildFailedException.class, () -> buildArtifacts(amnesiacBuilder(), out));
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java
index 585e6be..5ca6325 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java
@@ -62,6 +62,9 @@
 import com.google.devtools.build.lib.buildtool.SkyframeBuilder;
 import com.google.devtools.build.lib.clock.BlazeClock;
 import com.google.devtools.build.lib.clock.Clock;
+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.events.Reporter;
 import com.google.devtools.build.lib.events.StoredEventHandler;
 import com.google.devtools.build.lib.exec.SingleBuildFileCache;
@@ -419,28 +422,29 @@
   }
 
   /**
-   * Creates a TestAction from 'inputs' to 'outputs', and a new button, such
-   * that executing the action causes the button to be pressed.  The button is
-   * returned.
+   * Creates a TestAction from 'inputs' to 'outputs', and a new button, such that executing the
+   * action causes the button to be pressed. The button is returned.
    */
-  protected Button createActionButton(Collection<Artifact> inputs, Collection<Artifact> outputs) {
+  protected Button createActionButton(NestedSet<Artifact> inputs, ImmutableSet<Artifact> outputs) {
     Button button = new Button();
     registerAction(new TestAction(button, inputs, outputs));
     return button;
   }
 
   /**
-   * Creates a TestAction from 'inputs' to 'outputs', and a new counter, such
-   * that executing the action causes the counter to be incremented.  The
-   * counter is returned.
+   * Creates a TestAction from 'inputs' to 'outputs', and a new counter, such that executing the
+   * action causes the counter to be incremented. The counter is returned.
    */
-  protected Counter createActionCounter(Collection<Artifact> inputs, Collection<Artifact> outputs) {
+  protected Counter createActionCounter(
+      NestedSet<Artifact> inputs, ImmutableSet<Artifact> outputs) {
     Counter counter = new Counter();
     registerAction(new TestAction(counter, inputs, outputs));
     return counter;
   }
 
   protected static Set<Artifact> emptySet = Collections.emptySet();
+  protected static NestedSet<Artifact> emptyNestedSet =
+      NestedSetBuilder.emptySet(Order.STABLE_ORDER);
 
   protected void buildArtifacts(Builder builder, Artifact... artifacts)
       throws BuildFailedException, AbruptExitException, InterruptedException, TestExecException,
@@ -477,7 +481,7 @@
   /** {@link TestAction} that copies its single input to its single output. */
   protected static class CopyingAction extends TestAction {
     CopyingAction(Runnable effect, Artifact input, Artifact output) {
-      super(effect, ImmutableSet.of(input), ImmutableSet.of(output));
+      super(effect, NestedSetBuilder.create(Order.STABLE_ORDER, input), ImmutableSet.of(output));
     }
 
     @Override
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TopDownActionCacheTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TopDownActionCacheTest.java
index e4a0f6d..a5a98fa 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/TopDownActionCacheTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/TopDownActionCacheTest.java
@@ -18,14 +18,15 @@
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
 import com.google.devtools.build.lib.actions.ActionKeyContext;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.util.TestAction;
 import com.google.devtools.build.lib.actionsketch.ActionSketch;
+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.util.Fingerprint;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
-import java.util.Collection;
 import javax.annotation.Nullable;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -44,10 +45,14 @@
     buildArtifacts(amnesiacBuilder(), artifacts);
   }
 
+  private static NestedSet<Artifact> asNestedSet(Artifact... artifacts) {
+    return NestedSetBuilder.create(Order.STABLE_ORDER, artifacts);
+  }
+
   @Test
   public void testAmnesiacBuilderGetsTopDownHit() throws Exception {
     Artifact hello = createDerivedArtifact("hello");
-    Button button = createActionButton(emptySet, Sets.newHashSet(hello));
+    Button button = createActionButton(emptyNestedSet, ImmutableSet.of(hello));
 
     button.pressed = false;
     buildArtifacts(hello);
@@ -62,8 +67,8 @@
   public void testTransitiveTopDownCache() throws Exception {
     Artifact hello = createDerivedArtifact("hello");
     Artifact hello2 = createDerivedArtifact("hello2");
-    Button button = createActionButton(emptySet, ImmutableSet.of(hello));
-    Button button2 = createActionButton(ImmutableSet.of(hello), ImmutableSet.of(hello2));
+    Button button = createActionButton(emptyNestedSet, ImmutableSet.of(hello));
+    Button button2 = createActionButton(asNestedSet(hello), ImmutableSet.of(hello2));
 
     button.pressed = false;
     button2.pressed = false;
@@ -83,9 +88,9 @@
     Artifact hello = createDerivedArtifact("hello");
     Artifact hello2 = createDerivedArtifact("hello2");
 
-    ActionKeyButton button = createActionKeyButton(emptySet, ImmutableSet.of(hello), "abc");
+    ActionKeyButton button = createActionKeyButton(emptyNestedSet, ImmutableSet.of(hello), "abc");
     ActionKeyButton button2 =
-        createActionKeyButton(ImmutableSet.of(hello), ImmutableSet.of(hello2), "xyz");
+        createActionKeyButton(asNestedSet(hello), ImmutableSet.of(hello2), "xyz");
 
     button.pressed = false;
     button2.pressed = false;
@@ -102,8 +107,8 @@
     clearActions();
     hello = createDerivedArtifact("hello");
     hello2 = createDerivedArtifact("hello2");
-    button = createActionKeyButton(emptySet, ImmutableSet.of(hello), "abc");
-    button2 = createActionKeyButton(ImmutableSet.of(hello), ImmutableSet.of(hello2), "123");
+    button = createActionKeyButton(emptyNestedSet, ImmutableSet.of(hello), "abc");
+    button2 = createActionKeyButton(asNestedSet(hello), ImmutableSet.of(hello2), "123");
     button.pressed = false;
     button2.pressed = false;
     buildArtifacts(hello2);
@@ -119,8 +124,8 @@
     clearActions();
     hello = createDerivedArtifact("hello");
     hello2 = createDerivedArtifact("hello2");
-    button = createActionKeyButton(emptySet, ImmutableSet.of(hello), "456");
-    button2 = createActionKeyButton(ImmutableSet.of(hello), ImmutableSet.of(hello2), "123");
+    button = createActionKeyButton(emptyNestedSet, ImmutableSet.of(hello), "456");
+    button2 = createActionKeyButton(asNestedSet(hello), ImmutableSet.of(hello2), "123");
     button.pressed = false;
     button2.pressed = false;
     buildArtifacts(hello2);
@@ -141,7 +146,7 @@
     FileSystemUtils.writeContentAsLatin1(hello.getPath(), "content1");
 
     Artifact goodbye = createDerivedArtifact("goodbye");
-    Button button = createActionButton(ImmutableSet.of(hello), Sets.newHashSet(goodbye));
+    Button button = createActionButton(asNestedSet(hello), ImmutableSet.of(goodbye));
 
     button.pressed = false;
     buildArtifacts(goodbye);
@@ -187,7 +192,7 @@
     private final ActionKeyButton button;
 
     public MutableActionKeyAction(
-        ActionKeyButton button, Collection<Artifact> inputs, Collection<Artifact> outputs) {
+        ActionKeyButton button, NestedSet<Artifact> inputs, ImmutableSet<Artifact> outputs) {
       super(button, inputs, outputs);
       this.button = button;
     }
@@ -208,7 +213,7 @@
   }
 
   private ActionKeyButton createActionKeyButton(
-      Collection<Artifact> inputs, Collection<Artifact> outputs, String key) {
+      NestedSet<Artifact> inputs, ImmutableSet<Artifact> outputs, String key) {
     ActionKeyButton button = new ActionKeyButton(key);
     registerAction(new MutableActionKeyAction(button, inputs, outputs));
     return button;
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java
index ffe5aaf..6872135 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java
@@ -22,6 +22,7 @@
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.hash.Hashing;
@@ -50,6 +51,9 @@
 import com.google.devtools.build.lib.actions.util.TestAction;
 import com.google.devtools.build.lib.actions.util.TestAction.DummyAction;
 import com.google.devtools.build.lib.analysis.actions.SpawnActionTemplate;
+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.events.Event;
 import com.google.devtools.build.lib.events.EventKind;
 import com.google.devtools.build.lib.events.StoredEventHandler;
@@ -168,7 +172,9 @@
     final Artifact normalOutput = createDerivedArtifact("normal/out");
     Action testAction =
         new TestAction(
-            TestAction.NO_EFFECT, ImmutableList.of(outOne), ImmutableList.of(normalOutput)) {
+            TestAction.NO_EFFECT,
+            NestedSetBuilder.create(Order.STABLE_ORDER, outOne),
+            ImmutableSet.of(normalOutput)) {
           @Override
           public ActionResult execute(ActionExecutionContext actionExecutionContext) {
             try {
@@ -799,10 +805,14 @@
     TreeFileArtifact expectedOutputTreeFileArtifact2 =
         ActionInputHelper.treeFileArtifactWithNoGeneratingActionSet(
             artifact2, PathFragment.createAlreadyNormalized("child2"), secondOwner);
-    Action generateOutputAction = new DummyAction(
-        ImmutableList.<Artifact>of(treeFileArtifactA), expectedOutputTreeFileArtifact1);
-    Action noGenerateOutputAction = new DummyAction(
-        ImmutableList.<Artifact>of(treeFileArtifactB), expectedOutputTreeFileArtifact2);
+    Action generateOutputAction =
+        new DummyAction(
+            NestedSetBuilder.create(Order.STABLE_ORDER, treeFileArtifactA),
+            expectedOutputTreeFileArtifact1);
+    Action noGenerateOutputAction =
+        new DummyAction(
+            NestedSetBuilder.create(Order.STABLE_ORDER, treeFileArtifactB),
+            expectedOutputTreeFileArtifact2);
 
     actionTemplateExpansionFunction =
         new DummyActionTemplateExpansionFunction(
@@ -844,11 +854,14 @@
     TreeFileArtifact expectedOutputTreeFileArtifact2 =
         ActionInputHelper.treeFileArtifactWithNoGeneratingActionSet(
             artifact2, PathFragment.createAlreadyNormalized("child2"), secondOwner);
-    Action generateOutputAction = new DummyAction(
-        ImmutableList.<Artifact>of(treeFileArtifactA), expectedOutputTreeFileArtifact1);
-    Action noGenerateOutputAction = new NoOpDummyAction(
-        ImmutableList.<Artifact>of(treeFileArtifactB),
-        ImmutableList.<Artifact>of(expectedOutputTreeFileArtifact2));
+    Action generateOutputAction =
+        new DummyAction(
+            NestedSetBuilder.create(Order.STABLE_ORDER, treeFileArtifactA),
+            expectedOutputTreeFileArtifact1);
+    Action noGenerateOutputAction =
+        new NoOpDummyAction(
+            NestedSetBuilder.create(Order.STABLE_ORDER, treeFileArtifactB),
+            ImmutableSet.of(expectedOutputTreeFileArtifact2));
 
     actionTemplateExpansionFunction =
         new DummyActionTemplateExpansionFunction(
@@ -895,11 +908,14 @@
             artifact2,
             PathFragment.createAlreadyNormalized("child2"),
             ActionTemplateExpansionKey.of(artifact1.getArtifactOwner(), 1));
-    Action generateOutputAction = new DummyAction(
-        ImmutableList.<Artifact>of(treeFileArtifactA), expectedOutputTreeFileArtifact1);
-    Action throwingAction = new ThrowingDummyAction(
-        ImmutableList.<Artifact>of(treeFileArtifactB),
-        ImmutableList.<Artifact>of(expectedOutputTreeFileArtifact2));
+    Action generateOutputAction =
+        new DummyAction(
+            NestedSetBuilder.create(Order.STABLE_ORDER, treeFileArtifactA),
+            expectedOutputTreeFileArtifact1);
+    Action throwingAction =
+        new ThrowingDummyAction(
+            NestedSetBuilder.create(Order.STABLE_ORDER, treeFileArtifactB),
+            ImmutableSet.of(expectedOutputTreeFileArtifact2));
 
     actionTemplateExpansionFunction =
         new DummyActionTemplateExpansionFunction(
@@ -941,12 +957,14 @@
     TreeFileArtifact expectedOutputTreeFileArtifact2 =
         ActionInputHelper.treeFileArtifactWithNoGeneratingActionSet(
             artifact2, PathFragment.createAlreadyNormalized("child2"), secondOwner);
-    Action throwingAction = new ThrowingDummyAction(
-        ImmutableList.<Artifact>of(treeFileArtifactA),
-        ImmutableList.<Artifact>of(expectedOutputTreeFileArtifact1));
-    Action anotherThrowingAction = new ThrowingDummyAction(
-        ImmutableList.<Artifact>of(treeFileArtifactB),
-        ImmutableList.<Artifact>of(expectedOutputTreeFileArtifact2));
+    Action throwingAction =
+        new ThrowingDummyAction(
+            NestedSetBuilder.create(Order.STABLE_ORDER, treeFileArtifactA),
+            ImmutableSet.of(expectedOutputTreeFileArtifact1));
+    Action anotherThrowingAction =
+        new ThrowingDummyAction(
+            NestedSetBuilder.create(Order.STABLE_ORDER, treeFileArtifactB),
+            ImmutableSet.of(expectedOutputTreeFileArtifact2));
 
     actionTemplateExpansionFunction =
         new DummyActionTemplateExpansionFunction(
@@ -965,7 +983,8 @@
     // artifact1 is created by a action that throws.
     SpecialArtifact artifact1 = createTreeArtifact("treeArtifact1");
     registerAction(
-        new ThrowingDummyAction(ImmutableList.<Artifact>of(), ImmutableList.of(artifact1)));
+        new ThrowingDummyAction(
+            NestedSetBuilder.emptySet(Order.STABLE_ORDER), ImmutableSet.of(artifact1)));
 
     // artifact2 is a tree artifact generated by an action template.
     SpecialArtifact artifact2 = createTreeArtifact("treeArtifact2");
@@ -982,7 +1001,9 @@
   public void testEmptyInputAndOutputTreeArtifactInActionTemplate() throws Throwable {
     // artifact1 is an empty tree artifact which is generated by a single no-op dummy action.
     SpecialArtifact artifact1 = createTreeArtifact("treeArtifact1");
-    registerAction(new NoOpDummyAction(ImmutableList.<Artifact>of(), ImmutableList.of(artifact1)));
+    registerAction(
+        new NoOpDummyAction(
+            NestedSetBuilder.emptySet(Order.STABLE_ORDER), ImmutableSet.of(artifact1)));
 
     // artifact2 is a tree artifact generated by an action template that takes artifact1 as input.
     SpecialArtifact artifact2 = createTreeArtifact("treeArtifact2");
@@ -1049,9 +1070,12 @@
         Collection<TreeFileArtifact> inputFiles,
         Artifact output,
         Collection<TreeFileArtifact> outputFiles) {
-      super(effect,
-          input == null ? ImmutableList.<Artifact>of() : ImmutableList.of(input),
-          ImmutableList.of(output));
+      super(
+          effect,
+          input == null
+              ? NestedSetBuilder.emptySet(Order.STABLE_ORDER)
+              : NestedSetBuilder.create(Order.STABLE_ORDER, input),
+          ImmutableSet.of(output));
       Preconditions.checkArgument(
           inputFiles.isEmpty() || (input != null && input.isTreeArtifact()));
       Preconditions.checkArgument(output == null || output.isTreeArtifact());
@@ -1323,7 +1347,7 @@
 
   /** No-op action that does not generate the action outputs. */
   private static class NoOpDummyAction extends TestAction {
-    public NoOpDummyAction(Collection<Artifact> inputs, Collection<Artifact> outputs) {
+    public NoOpDummyAction(NestedSet<Artifact> inputs, ImmutableSet<Artifact> outputs) {
       super(NO_EFFECT, inputs, outputs);
     }
 
@@ -1337,7 +1361,7 @@
 
   /** No-op action that throws when executed */
   private static class ThrowingDummyAction extends TestAction {
-    public ThrowingDummyAction(Collection<Artifact> inputs, Collection<Artifact> outputs) {
+    public ThrowingDummyAction(NestedSet<Artifact> inputs, ImmutableSet<Artifact> outputs) {
       super(NO_EFFECT, inputs, outputs);
     }
 
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java
index 7813b24..fcf94f5 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java
@@ -39,6 +39,8 @@
 import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
 import com.google.devtools.build.lib.actions.cache.DigestUtils;
 import com.google.devtools.build.lib.actions.util.TestAction.DummyAction;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.events.NullEventHandler;
 import com.google.devtools.build.lib.vfs.FileStatus;
 import com.google.devtools.build.lib.vfs.FileStatusWithDigestAdapter;
@@ -234,7 +236,7 @@
             execPath,
             ALL_OWNER,
             SpecialArtifactType.TREE);
-    actions.add(new DummyAction(ImmutableList.<Artifact>of(), output));
+    actions.add(new DummyAction(NestedSetBuilder.emptySet(Order.STABLE_ORDER), output));
     FileSystemUtils.createDirectoryAndParents(fullPath);
     return output;
   }