Rename Root to ArtifactRoot.

This is slightly more descriptive, and we will potentially want to use the name Root for a broader concept shared between ArtifactRoot and RootedPath.

PiperOrigin-RevId: 182082367
diff --git a/src/test/java/com/google/devtools/build/lib/actions/ActionCacheCheckerTest.java b/src/test/java/com/google/devtools/build/lib/actions/ActionCacheCheckerTest.java
index c6de334..8892fcf 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/ActionCacheCheckerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/ActionCacheCheckerTest.java
@@ -274,15 +274,16 @@
 
   @Test
   public void testMiddleman_DifferentFiles() throws Exception {
-    Action action = new NullMiddlemanAction() {
-      @Override
-      public synchronized Iterable<Artifact> getInputs() {
-        FileSystem fileSystem = getPrimaryOutput().getPath().getFileSystem();
-        Path path = fileSystem.getPath("/input");
-        Root root = Root.asSourceRoot(fileSystem.getPath("/"));
-        return ImmutableList.of(new Artifact(path, root));
-      }
-    };
+    Action action =
+        new NullMiddlemanAction() {
+          @Override
+          public synchronized Iterable<Artifact> getInputs() {
+            FileSystem fileSystem = getPrimaryOutput().getPath().getFileSystem();
+            Path path = fileSystem.getPath("/input");
+            ArtifactRoot root = ArtifactRoot.asSourceRoot(fileSystem.getPath("/"));
+            return ImmutableList.of(new Artifact(path, root));
+          }
+        };
     runAction(action);  // Not cached so recorded as different deps.
     FileSystemUtils.writeContentAsLatin1(action.getPrimaryInput().getPath(), "modified");
     runAction(action);  // Cache miss because input files were modified.
diff --git a/src/test/java/com/google/devtools/build/lib/actions/ActionLookupValueTest.java b/src/test/java/com/google/devtools/build/lib/actions/ActionLookupValueTest.java
index 5ae6c37..e2ddd4f 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/ActionLookupValueTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/ActionLookupValueTest.java
@@ -58,7 +58,7 @@
   public void testActionNotPresentAfterEvaluation() {
     Path execRoot = fs.getPath("/execroot");
     Path outputRootPath = execRoot.getRelative("blaze-out");
-    Root root = Root.asDerivedRoot(execRoot, outputRootPath);
+    ArtifactRoot root = ArtifactRoot.asDerivedRoot(execRoot, outputRootPath);
     Action normalAction = mock(Action.class);
     Artifact normalArtifact = new Artifact(PathFragment.create("normal"), root);
     when(normalAction.getOutputs()).thenReturn(ImmutableSet.of(normalArtifact));
diff --git a/src/test/java/com/google/devtools/build/lib/actions/ArtifactFactoryTest.java b/src/test/java/com/google/devtools/build/lib/actions/ArtifactFactoryTest.java
index 5c6005d..94b1a0f 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/ArtifactFactoryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/ArtifactFactoryTest.java
@@ -50,10 +50,10 @@
   private Scratch scratch = new Scratch();
 
   private Path execRoot;
-  private Root clientRoot;
-  private Root clientRoRoot;
-  private Root alienRoot;
-  private Root outRoot;
+  private ArtifactRoot clientRoot;
+  private ArtifactRoot clientRoRoot;
+  private ArtifactRoot alienRoot;
+  private ArtifactRoot outRoot;
 
   private PathFragment fooPath;
   private PackageIdentifier fooPackage;
@@ -73,10 +73,10 @@
   @Before
   public final void createFiles() throws Exception  {
     execRoot = scratch.dir("/output/workspace");
-    clientRoot = Root.asSourceRoot(scratch.dir("/client/workspace"));
-    clientRoRoot = Root.asSourceRoot(scratch.dir("/client/RO/workspace"));
-    alienRoot = Root.asSourceRoot(scratch.dir("/client/workspace"));
-    outRoot = Root.asDerivedRoot(execRoot, execRoot.getRelative("out-root/x/bin"));
+    clientRoot = ArtifactRoot.asSourceRoot(scratch.dir("/client/workspace"));
+    clientRoRoot = ArtifactRoot.asSourceRoot(scratch.dir("/client/RO/workspace"));
+    alienRoot = ArtifactRoot.asSourceRoot(scratch.dir("/client/workspace"));
+    outRoot = ArtifactRoot.asDerivedRoot(execRoot, execRoot.getRelative("out-root/x/bin"));
 
     fooPath = PathFragment.create("foo");
     fooPackage = PackageIdentifier.createInMainRepo(fooPath);
@@ -95,7 +95,7 @@
   }
 
   private void setupRoots() {
-    Map<PackageIdentifier, Root> packageRootMap = new HashMap<>();
+    Map<PackageIdentifier, ArtifactRoot> packageRootMap = new HashMap<>();
     packageRootMap.put(fooPackage, clientRoot);
     packageRootMap.put(barPackage, clientRoRoot);
     packageRootMap.put(alienPackage, alienRoot);
@@ -155,8 +155,8 @@
   public void testResolveArtifactWithUpLevelFailsCleanly() throws Exception {
     // We need a package in the root directory to make every exec path (even one with up-level
     // references) be in a package.
-    Map<PackageIdentifier, Root> packageRoots = ImmutableMap.of(
-        PackageIdentifier.createInMainRepo(PathFragment.create("")), clientRoot);
+    Map<PackageIdentifier, ArtifactRoot> packageRoots =
+        ImmutableMap.of(PackageIdentifier.createInMainRepo(PathFragment.create("")), clientRoot);
     artifactFactory.setPackageRoots(packageRoots::get);
     PathFragment outsideWorkspace = PathFragment.create("../foo");
     PathFragment insideWorkspace =
@@ -211,17 +211,18 @@
   }
 
   private static class MockPackageRootResolver implements PackageRootResolver {
-    private Map<PathFragment, Root> packageRoots = Maps.newHashMap();
+    private Map<PathFragment, ArtifactRoot> packageRoots = Maps.newHashMap();
 
-    public void setPackageRoots(Map<PackageIdentifier, Root> packageRoots) {
-      for (Entry<PackageIdentifier, Root> packageRoot : packageRoots.entrySet()) {
+    public void setPackageRoots(Map<PackageIdentifier, ArtifactRoot> packageRoots) {
+      for (Entry<PackageIdentifier, ArtifactRoot> packageRoot : packageRoots.entrySet()) {
         this.packageRoots.put(packageRoot.getKey().getPackageFragment(), packageRoot.getValue());
       }
     }
 
     @Override
-    public Map<PathFragment, Root> findPackageRootsForFiles(Iterable<PathFragment> execPaths) {
-      Map<PathFragment, Root> result = new HashMap<>();
+    public Map<PathFragment, ArtifactRoot> findPackageRootsForFiles(
+        Iterable<PathFragment> execPaths) {
+      Map<PathFragment, ArtifactRoot> result = new HashMap<>();
       for (PathFragment execPath : execPaths) {
         for (PathFragment dir = execPath.getParentDirectory(); dir != null;
             dir = dir.getParentDirectory()) {
@@ -238,7 +239,7 @@
 
     @Override
     @Nullable
-    public Map<PathFragment, Root> findPackageRoots(Iterable<PathFragment> execPaths) {
+    public Map<PathFragment, ArtifactRoot> findPackageRoots(Iterable<PathFragment> execPaths) {
       return null; // unused
     }
   }
diff --git a/src/test/java/com/google/devtools/build/lib/actions/RootTest.java b/src/test/java/com/google/devtools/build/lib/actions/ArtifactRootTest.java
similarity index 79%
rename from src/test/java/com/google/devtools/build/lib/actions/RootTest.java
rename to src/test/java/com/google/devtools/build/lib/actions/ArtifactRootTest.java
index 36ede38..dfe4e07 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/RootTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/ArtifactRootTest.java
@@ -25,15 +25,15 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
-/** Tests for {@link Root}. */
+/** Tests for {@link ArtifactRoot}. */
 @RunWith(JUnit4.class)
-public class RootTest {
+public class ArtifactRootTest {
   private Scratch scratch = new Scratch();
 
   @Test
   public void testAsSourceRoot() throws IOException {
     Path sourceDir = scratch.dir("/source");
-    Root root = Root.asSourceRoot(sourceDir);
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(sourceDir);
     assertThat(root.isSourceRoot()).isTrue();
     assertThat(root.getExecPath()).isEqualTo(PathFragment.EMPTY_FRAGMENT);
     assertThat(root.getPath()).isEqualTo(sourceDir);
@@ -43,7 +43,7 @@
   @Test
   public void testBadAsSourceRoot() {
     try {
-      Root.asSourceRoot(null);
+      ArtifactRoot.asSourceRoot(null);
       fail();
     } catch (NullPointerException expected) {
     }
@@ -53,7 +53,7 @@
   public void testAsDerivedRoot() throws IOException {
     Path execRoot = scratch.dir("/exec");
     Path rootDir = scratch.dir("/exec/root");
-    Root root = Root.asDerivedRoot(execRoot, rootDir);
+    ArtifactRoot root = ArtifactRoot.asDerivedRoot(execRoot, rootDir);
     assertThat(root.isSourceRoot()).isFalse();
     assertThat(root.getExecPath()).isEqualTo(PathFragment.create("root"));
     assertThat(root.getPath()).isEqualTo(rootDir);
@@ -65,7 +65,7 @@
     try {
       Path execRoot = scratch.dir("/exec");
       Path outsideDir = scratch.dir("/not_exec");
-      Root.asDerivedRoot(execRoot, outsideDir);
+      ArtifactRoot.asDerivedRoot(execRoot, outsideDir);
       fail();
     } catch (IllegalArgumentException expected) {
     }
@@ -75,7 +75,7 @@
   public void testBadAsDerivedRootSameForBoth() throws IOException {
     try {
       Path execRoot = scratch.dir("/exec");
-      Root.asDerivedRoot(execRoot, execRoot);
+      ArtifactRoot.asDerivedRoot(execRoot, execRoot);
       fail();
     } catch (IllegalArgumentException expected) {
     }
@@ -85,7 +85,7 @@
   public void testBadAsDerivedRootNullDir() throws IOException {
     try {
       Path execRoot = scratch.dir("/exec");
-      Root.asDerivedRoot(execRoot, null);
+      ArtifactRoot.asDerivedRoot(execRoot, null);
       fail();
     } catch (NullPointerException expected) {
     }
@@ -95,7 +95,7 @@
   public void testBadAsDerivedRootNullExecRoot() throws IOException {
     try {
       Path execRoot = scratch.dir("/exec");
-      Root.asDerivedRoot(null, execRoot);
+      ArtifactRoot.asDerivedRoot(null, execRoot);
       fail();
     } catch (NullPointerException expected) {
     }
@@ -107,11 +107,11 @@
     Path rootDir = scratch.dir("/exec/root");
     Path otherRootDir = scratch.dir("/");
     Path sourceDir = scratch.dir("/source");
-    Root rootA = Root.asDerivedRoot(execRoot, rootDir);
-    assertEqualsAndHashCode(true, rootA, Root.asDerivedRoot(execRoot, rootDir));
-    assertEqualsAndHashCode(false, rootA, Root.asSourceRoot(sourceDir));
-    assertEqualsAndHashCode(false, rootA, Root.asSourceRoot(rootDir));
-    assertEqualsAndHashCode(false, rootA, Root.asDerivedRoot(otherRootDir, rootDir));
+    ArtifactRoot rootA = ArtifactRoot.asDerivedRoot(execRoot, rootDir);
+    assertEqualsAndHashCode(true, rootA, ArtifactRoot.asDerivedRoot(execRoot, rootDir));
+    assertEqualsAndHashCode(false, rootA, ArtifactRoot.asSourceRoot(sourceDir));
+    assertEqualsAndHashCode(false, rootA, ArtifactRoot.asSourceRoot(rootDir));
+    assertEqualsAndHashCode(false, rootA, ArtifactRoot.asDerivedRoot(otherRootDir, rootDir));
   }
 
   public void assertEqualsAndHashCode(boolean expected, Object a, Object b) {
diff --git a/src/test/java/com/google/devtools/build/lib/actions/ArtifactTest.java b/src/test/java/com/google/devtools/build/lib/actions/ArtifactTest.java
index dda385f..681b2a3 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/ArtifactTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/ArtifactTest.java
@@ -40,14 +40,14 @@
 public class ArtifactTest {
   private Scratch scratch;
   private Path execDir;
-  private Root rootDir;
+  private ArtifactRoot rootDir;
   private final ActionKeyContext actionKeyContext = new ActionKeyContext();
 
   @Before
   public final void setRootDir() throws Exception  {
     scratch = new Scratch();
     execDir = scratch.dir("/exec");
-    rootDir = Root.asDerivedRoot(execDir, scratch.dir("/exec/root"));
+    rootDir = ArtifactRoot.asDerivedRoot(execDir, scratch.dir("/exec/root"));
   }
 
   @Test
@@ -55,7 +55,7 @@
     Path f1 = scratch.file("/exec/dir/file.ext");
     Path bogusDir = scratch.file("/exec/dir/bogus");
     try {
-      new Artifact(f1, Root.asDerivedRoot(execDir, bogusDir), f1.relativeTo(execDir));
+      new Artifact(f1, ArtifactRoot.asDerivedRoot(execDir, bogusDir), f1.relativeTo(execDir));
       fail("Expected IllegalArgumentException constructing artifact with a bad root dir");
     } catch (IllegalArgumentException expected) {}
   }
@@ -97,7 +97,7 @@
   @Test
   public void testRootPrefixedExecPath_noRoot() throws IOException {
     Path f1 = scratch.file("/exec/dir/file.ext");
-    Artifact a1 = new Artifact(f1.relativeTo(execDir), Root.asSourceRoot(execDir));
+    Artifact a1 = new Artifact(f1.relativeTo(execDir), ArtifactRoot.asSourceRoot(execDir));
     assertThat(Artifact.asRootPrefixedExecPath(a1)).isEqualTo(":dir/file.ext");
   }
 
@@ -128,7 +128,7 @@
 
   @Test
   public void testGetFilename() throws Exception {
-    Root root = Root.asSourceRoot(scratch.dir("/foo"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.dir("/foo"));
     Artifact javaFile = new Artifact(scratch.file("/foo/Bar.java"), root);
     Artifact generatedHeader = new Artifact(scratch.file("/foo/bar.proto.h"), root);
     Artifact generatedCc = new Artifact(scratch.file("/foo/bar.proto.cc"), root);
@@ -141,7 +141,7 @@
 
   @Test
   public void testGetExtension() throws Exception {
-    Root root = Root.asSourceRoot(scratch.dir("/foo"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.dir("/foo"));
     Artifact javaFile = new Artifact(scratch.file("/foo/Bar.java"), root);
     assertThat(javaFile.getExtension()).isEqualTo("java");
   }
@@ -154,12 +154,14 @@
 
   private List<Artifact> getFooBarArtifacts(MutableActionGraph actionGraph, boolean collapsedList)
       throws Exception {
-    Root root = Root.asSourceRoot(scratch.dir("/foo"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.dir("/foo"));
     Artifact aHeader1 = new Artifact(scratch.file("/foo/bar1.h"), root);
     Artifact aHeader2 = new Artifact(scratch.file("/foo/bar2.h"), root);
     Artifact aHeader3 = new Artifact(scratch.file("/foo/bar3.h"), root);
-    Artifact middleman = new Artifact(PathFragment.create("middleman"),
-        Root.middlemanRoot(scratch.dir("/foo"), scratch.dir("/foo/out")));
+    Artifact middleman =
+        new Artifact(
+            PathFragment.create("middleman"),
+            ArtifactRoot.middlemanRoot(scratch.dir("/foo"), scratch.dir("/foo/out")));
     actionGraph.registerAction(new MiddlemanAction(ActionsTestUtil.NULL_ACTION_OWNER,
         ImmutableList.of(aHeader1, aHeader2, aHeader3), middleman, "desc",
         MiddlemanType.AGGREGATING_MIDDLEMAN));
@@ -270,7 +272,7 @@
 
   @Test
   public void testRootRelativePathIsSameAsExecPath() throws Exception {
-    Root root = Root.asSourceRoot(scratch.dir("/foo"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.dir("/foo"));
     Artifact a = new Artifact(scratch.file("/foo/bar1.h"), root);
     assertThat(a.getRootRelativePath()).isSameAs(a.getExecPath());
   }
@@ -281,7 +283,7 @@
     Artifact a =
         new Artifact(
             scratch.file("/a/b/c"),
-            Root.asDerivedRoot(execRoot, scratch.dir("/a/b")),
+            ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/a/b")),
             PathFragment.create("b/c"));
     assertThat(a.toDetailString()).isEqualTo("[[/a]b]c");
   }
@@ -292,7 +294,7 @@
       Path execRoot = scratch.getFileSystem().getPath("/");
       new Artifact(
           scratch.file("/a/b/c"),
-          Root.asDerivedRoot(execRoot, scratch.dir("/a")),
+          ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/a")),
           PathFragment.create("c"));
       fail();
     } catch (IllegalArgumentException e) {
@@ -305,7 +307,8 @@
   public void testSerializeToString() throws Exception {
     Path execRoot = scratch.getFileSystem().getPath("/");
     assertThat(
-            new Artifact(scratch.file("/a/b/c"), Root.asDerivedRoot(execRoot, scratch.dir("/a")))
+            new Artifact(
+                    scratch.file("/a/b/c"), ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/a")))
                 .serializeToString())
         .isEqualTo("a/b/c /3");
   }
@@ -314,7 +317,7 @@
   public void testSerializeToStringWithExecPath() throws Exception {
     Path execRoot = scratch.getFileSystem().getPath("/");
     Path path = scratch.file("/aaa/bbb/ccc");
-    Root root = Root.asDerivedRoot(execRoot, scratch.dir("/aaa/bbb"));
+    ArtifactRoot root = ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/aaa/bbb"));
     PathFragment execPath = PathFragment.create("bbb/ccc");
 
     assertThat(new Artifact(path, root, execPath).serializeToString()).isEqualTo("bbb/ccc /3");
@@ -326,7 +329,7 @@
     assertThat(
             new Artifact(
                     scratch.file("/aa/b/c"),
-                    Root.asDerivedRoot(execRoot, scratch.dir("/aa")),
+                    ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/aa")),
                     PathFragment.create("b/c"),
                     new LabelArtifactOwner(Label.parseAbsoluteUnchecked("//foo:bar")))
                 .serializeToString())
@@ -343,7 +346,7 @@
   @Test
   public void testDirnameInExecutionDir() throws Exception {
     Artifact artifact =
-        new Artifact(scratch.file("/foo/bar.txt"), Root.asSourceRoot(scratch.dir("/foo")));
+        new Artifact(scratch.file("/foo/bar.txt"), ArtifactRoot.asSourceRoot(scratch.dir("/foo")));
 
     assertThat(artifact.getDirname()).isEqualTo(".");
   }
@@ -360,26 +363,30 @@
   @Test
   public void testIsSourceArtifact() throws Exception {
     assertThat(
-        new Artifact(scratch.file("/src/foo.cc"), Root.asSourceRoot(scratch.dir("/")),
-            PathFragment.create("src/foo.cc"))
-            .isSourceArtifact())
+            new Artifact(
+                    scratch.file("/src/foo.cc"),
+                    ArtifactRoot.asSourceRoot(scratch.dir("/")),
+                    PathFragment.create("src/foo.cc"))
+                .isSourceArtifact())
         .isTrue();
     assertThat(
-        new Artifact(scratch.file("/genfiles/aaa/bar.out"),
-            Root.asDerivedRoot(scratch.dir("/genfiles"), scratch.dir("/genfiles/aaa")))
-            .isSourceArtifact())
+            new Artifact(
+                    scratch.file("/genfiles/aaa/bar.out"),
+                    ArtifactRoot.asDerivedRoot(
+                        scratch.dir("/genfiles"), scratch.dir("/genfiles/aaa")))
+                .isSourceArtifact())
         .isFalse();
-
   }
 
   @Test
   public void testGetRoot() throws Exception {
     Path execRoot = scratch.getFileSystem().getPath("/");
-    Root root = Root.asDerivedRoot(execRoot, scratch.dir("/newRoot"));
+    ArtifactRoot root = ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/newRoot"));
     assertThat(new Artifact(scratch.file("/newRoot/foo"), root).getRoot()).isEqualTo(root);
   }
 
   private Artifact createDirNameArtifact() throws Exception {
-    return new Artifact(scratch.file("/aaa/bbb/ccc/ddd"), Root.asSourceRoot(scratch.dir("/")));
+    return new Artifact(
+        scratch.file("/aaa/bbb/ccc/ddd"), ArtifactRoot.asSourceRoot(scratch.dir("/")));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/actions/CompositeRunfilesSupplierTest.java b/src/test/java/com/google/devtools/build/lib/actions/CompositeRunfilesSupplierTest.java
index e799800..dc6f752 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/CompositeRunfilesSupplierTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/CompositeRunfilesSupplierTest.java
@@ -40,13 +40,13 @@
   private RunfilesSupplier mockSecond;
 
   private Path execRoot;
-  private Root rootDir;
+  private ArtifactRoot rootDir;
 
   @Before
   public final void createMocks() throws IOException {
     Scratch scratch = new Scratch();
     execRoot = scratch.getFileSystem().getPath("/");
-    rootDir = Root.asDerivedRoot(execRoot, scratch.dir("/fake/root/dont/matter"));
+    rootDir = ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/fake/root/dont/matter"));
 
     mockFirst = mock(RunfilesSupplier.class);
     mockSecond = mock(RunfilesSupplier.class);
@@ -131,7 +131,7 @@
         shared, firstSharedMappings);
    }
 
-  private static Map<PathFragment, Artifact> mkMappings(Root rootDir, String... paths) {
+  private static Map<PathFragment, Artifact> mkMappings(ArtifactRoot rootDir, String... paths) {
     ImmutableMap.Builder<PathFragment, Artifact> builder = ImmutableMap.builder();
     for (String path : paths) {
       builder.put(PathFragment.create(path), mkArtifact(rootDir, path));
@@ -139,11 +139,11 @@
     return builder.build();
   }
 
-  private static Artifact mkArtifact(Root rootDir, String path) {
+  private static Artifact mkArtifact(ArtifactRoot rootDir, String path) {
     return new Artifact(PathFragment.create(path), rootDir);
   }
 
-  private static List<Artifact> mkArtifacts(Root rootDir, String... paths) {
+  private static List<Artifact> mkArtifacts(ArtifactRoot rootDir, String... paths) {
     ImmutableList.Builder<Artifact> builder = ImmutableList.builder();
     for (String path : paths) {
       builder.add(mkArtifact(rootDir, path));
diff --git a/src/test/java/com/google/devtools/build/lib/actions/CustomCommandLineTest.java b/src/test/java/com/google/devtools/build/lib/actions/CustomCommandLineTest.java
index a907739..5227dba 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/CustomCommandLineTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/CustomCommandLineTest.java
@@ -44,14 +44,14 @@
 public class CustomCommandLineTest {
 
   private Scratch scratch;
-  private Root rootDir;
+  private ArtifactRoot rootDir;
   private Artifact artifact1;
   private Artifact artifact2;
 
   @Before
   public void createArtifacts() throws Exception  {
     scratch = new Scratch();
-    rootDir = Root.asSourceRoot(scratch.dir("/exec/root"));
+    rootDir = ArtifactRoot.asSourceRoot(scratch.dir("/exec/root"));
     artifact1 = new Artifact(scratch.file("/exec/root/dir/file1.txt"), rootDir);
     artifact2 = new Artifact(scratch.file("/exec/root/dir/file2.txt"), rootDir);
   }
diff --git a/src/test/java/com/google/devtools/build/lib/actions/ExecutableSymlinkActionTest.java b/src/test/java/com/google/devtools/build/lib/actions/ExecutableSymlinkActionTest.java
index 391ccf5..28da727 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/ExecutableSymlinkActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/ExecutableSymlinkActionTest.java
@@ -35,8 +35,8 @@
 @RunWith(JUnit4.class)
 public class ExecutableSymlinkActionTest {
   private Scratch scratch = new Scratch();
-  private Root inputRoot;
-  private Root outputRoot;
+  private ArtifactRoot inputRoot;
+  private ArtifactRoot outputRoot;
   TestFileOutErr outErr;
   private Executor executor;
   private final ActionKeyContext actionKeyContext = new ActionKeyContext();
@@ -45,8 +45,8 @@
   public final void createExecutor() throws Exception  {
     final Path inputDir = scratch.dir("/in");
     Path execRoot = scratch.getFileSystem().getPath("/");
-    inputRoot = Root.asDerivedRoot(execRoot, inputDir);
-    outputRoot = Root.asDerivedRoot(execRoot, scratch.dir("/out"));
+    inputRoot = ArtifactRoot.asDerivedRoot(execRoot, inputDir);
+    outputRoot = ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/out"));
     outErr = new TestFileOutErr();
     executor = new DummyExecutor(scratch.getFileSystem(), inputDir);
   }
diff --git a/src/test/java/com/google/devtools/build/lib/actions/FailActionTest.java b/src/test/java/com/google/devtools/build/lib/actions/FailActionTest.java
index 5b39c35..c1eac8e 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/FailActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/FailActionTest.java
@@ -42,8 +42,10 @@
   @Before
   public final void setUp() throws Exception  {
     errorMessage = "An error just happened.";
-    anOutput = new Artifact(scratch.file("/out/foo"),
-        Root.asDerivedRoot(scratch.dir("/"), scratch.dir("/out")));
+    anOutput =
+        new Artifact(
+            scratch.file("/out/foo"),
+            ArtifactRoot.asDerivedRoot(scratch.dir("/"), scratch.dir("/out")));
     outputs = ImmutableList.of(anOutput);
     failAction = new FailAction(NULL_ACTION_OWNER, outputs, errorMessage);
     actionGraph.registerAction(failAction);
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 7d4a752..5de14d9 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
@@ -45,13 +45,13 @@
     Path execRoot = fileSystem.getPath("/");
     Path root = fileSystem.getPath("/root");
     Path path = root.getRelative("foo");
-    Artifact output = new Artifact(path, Root.asDerivedRoot(execRoot, root));
+    Artifact output = new Artifact(path, ArtifactRoot.asDerivedRoot(execRoot, root));
     Action action = new TestAction(TestAction.NO_EFFECT,
         ImmutableSet.<Artifact>of(), ImmutableSet.of(output));
     actionGraph.registerAction(action);
     actionGraph.unregisterAction(action);
     path = root.getRelative("bar");
-    output = new Artifact(path, Root.asDerivedRoot(execRoot, root));
+    output = new Artifact(path, ArtifactRoot.asDerivedRoot(execRoot, root));
     Action action2 = new TestAction(TestAction.NO_EFFECT,
         ImmutableSet.<Artifact>of(), ImmutableSet.of(output));
     actionGraph.registerAction(action);
@@ -65,7 +65,7 @@
     Path execRoot = fileSystem.getPath("/");
     Path root = fileSystem.getPath("/root");
     Path path = root.getRelative("/root/foo");
-    Artifact output = new Artifact(path, Root.asDerivedRoot(execRoot, root));
+    Artifact output = new Artifact(path, ArtifactRoot.asDerivedRoot(execRoot, root));
     Action action = new TestAction(TestAction.NO_EFFECT,
         ImmutableSet.<Artifact>of(), ImmutableSet.of(output));
     actionGraph.registerAction(action);
@@ -94,7 +94,7 @@
       Path execRoot = fileSystem.getPath("/");
       Path root = fileSystem.getPath("/root");
       Path path = root.getRelative("foo");
-      output = new Artifact(path, Root.asDerivedRoot(execRoot, root));
+      output = new Artifact(path, ArtifactRoot.asDerivedRoot(execRoot, root));
       allActions.add(new TestAction(
           TestAction.NO_EFFECT, ImmutableSet.<Artifact>of(), ImmutableSet.of(output)));
     }
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 ecd3fc3..c3f8e0f 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
@@ -42,11 +42,11 @@
 import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
 import com.google.devtools.build.lib.actions.ArtifactResolver;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.Executor;
 import com.google.devtools.build.lib.actions.MutableActionGraph;
 import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
 import com.google.devtools.build.lib.actions.PackageRootResolver;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.actions.cache.Md5Digest;
 import com.google.devtools.build.lib.actions.cache.Metadata;
 import com.google.devtools.build.lib.actions.cache.MetadataHandler;
@@ -243,9 +243,10 @@
     }
   }
 
-  public static final Artifact DUMMY_ARTIFACT = new Artifact(
-      PathFragment.create("dummy"),
-      Root.asSourceRoot(new InMemoryFileSystem().getRootDirectory()));
+  public static final Artifact DUMMY_ARTIFACT =
+      new Artifact(
+          PathFragment.create("dummy"),
+          ArtifactRoot.asSourceRoot(new InMemoryFileSystem().getRootDirectory()));
 
   public static final ActionOwner NULL_ACTION_OWNER =
       ActionOwner.create(
@@ -673,12 +674,12 @@
   public static class FakeArtifactResolverBase implements ArtifactResolver {
     @Override
     public Artifact getSourceArtifact(
-        PathFragment execPath, Root root, ArtifactOwner owner) {
+        PathFragment execPath, ArtifactRoot root, ArtifactOwner owner) {
       throw new UnsupportedOperationException();
     }
 
     @Override
-    public Artifact getSourceArtifact(PathFragment execPath, Root root) {
+    public Artifact getSourceArtifact(PathFragment execPath, ArtifactRoot root) {
       throw new UnsupportedOperationException();
     }
 
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/LocationFunctionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/LocationFunctionTest.java
index 676255f..f1de38e 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/LocationFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/LocationFunctionTest.java
@@ -19,7 +19,7 @@
 
 import com.google.common.base.Suppliers;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.analysis.LocationExpander.LocationFunction;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.vfs.FileSystem;
@@ -47,9 +47,10 @@
   private Artifact makeArtifact(String path) {
     if (path.startsWith("/exec/out")) {
       return new Artifact(
-          fs.getPath(path), Root.asDerivedRoot(fs.getPath("/exec"), fs.getPath("/exec/out")));
+          fs.getPath(path),
+          ArtifactRoot.asDerivedRoot(fs.getPath("/exec"), fs.getPath("/exec/out")));
     } else {
-      return new Artifact(fs.getPath(path), Root.asSourceRoot(fs.getPath("/exec")));
+      return new Artifact(fs.getPath(path), ArtifactRoot.asSourceRoot(fs.getPath("/exec")));
     }
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/RunfilesSupplierImplTest.java b/src/test/java/com/google/devtools/build/lib/analysis/RunfilesSupplierImplTest.java
index 3967b0e..952d013 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/RunfilesSupplierImplTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/RunfilesSupplierImplTest.java
@@ -19,7 +19,7 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.RunfilesSupplier;
 import com.google.devtools.build.lib.testutil.Scratch;
 import com.google.devtools.build.lib.vfs.Path;
@@ -36,17 +36,18 @@
 public class RunfilesSupplierImplTest {
 
   private Path execRoot;
-  private Root rootDir;
-  private Root middlemanRoot;
+  private ArtifactRoot rootDir;
+  private ArtifactRoot middlemanRoot;
 
   @Before
   public final void setRoot() throws IOException {
     Scratch scratch = new Scratch();
     execRoot = scratch.getFileSystem().getPath("/");
-    rootDir = Root.asDerivedRoot(execRoot, scratch.dir("/fake/root/dont/matter"));
+    rootDir = ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/fake/root/dont/matter"));
 
     Path middlemanExecPath = scratch.dir("/still/fake/root/dont/matter");
-    middlemanRoot = Root.middlemanRoot(middlemanExecPath, middlemanExecPath.getChild("subdir"));
+    middlemanRoot =
+        ArtifactRoot.middlemanRoot(middlemanExecPath, middlemanExecPath.getChild("subdir"));
   }
 
   @Test
@@ -90,7 +91,7 @@
     return new Runfiles.Builder("TESTING", false).addArtifacts(artifacts).build();
   }
 
-  private static List<Artifact> mkArtifacts(Root rootDir, String... paths) {
+  private static List<Artifact> mkArtifacts(ArtifactRoot rootDir, String... paths) {
     ImmutableList.Builder<Artifact> builder = ImmutableList.builder();
     for (String path : paths) {
       builder.add(new Artifact(PathFragment.create(path), rootDir));
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/RunfilesTest.java b/src/test/java/com/google/devtools/build/lib/analysis/RunfilesTest.java
index 5a16caa..ec184e8 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/RunfilesTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/RunfilesTest.java
@@ -21,7 +21,7 @@
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Maps;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.events.EventKind;
 import com.google.devtools.build.lib.testutil.FoundationTestCase;
@@ -51,7 +51,7 @@
   public void testFilterListForObscuringSymlinksCatchesBadObscurer() throws Exception {
     Map<PathFragment, Artifact> obscuringMap = new HashMap<>();
     PathFragment pathA = PathFragment.create("a");
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     Artifact artifactA = new Artifact(PathFragment.create("a"), root);
     obscuringMap.put(pathA, artifactA);
     obscuringMap.put(PathFragment.create("a/b"), new Artifact(PathFragment.create("c/b"),
@@ -65,7 +65,7 @@
   public void testFilterListForObscuringSymlinksCatchesBadGrandParentObscurer() throws Exception {
     Map<PathFragment, Artifact> obscuringMap = new HashMap<>();
     PathFragment pathA = PathFragment.create("a");
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     Artifact artifactA = new Artifact(PathFragment.create("a"),
                                           root);
     obscuringMap.put(pathA, artifactA);
@@ -80,7 +80,7 @@
   public void testFilterListForObscuringSymlinksCatchesBadObscurerNoListener() throws Exception {
     Map<PathFragment, Artifact> obscuringMap = new HashMap<>();
     PathFragment pathA = PathFragment.create("a");
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     Artifact artifactA = new Artifact(PathFragment.create("a"),
                                           root);
     obscuringMap.put(pathA, artifactA);
@@ -94,7 +94,7 @@
   public void testFilterListForObscuringSymlinksIgnoresOkObscurer() throws Exception {
     Map<PathFragment, Artifact> obscuringMap = new HashMap<>();
     PathFragment pathA = PathFragment.create("a");
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     Artifact artifactA = new Artifact(PathFragment.create("a"),
                                           root);
     obscuringMap.put(pathA, artifactA);
@@ -110,7 +110,7 @@
   public void testFilterListForObscuringSymlinksNoObscurers() throws Exception {
     Map<PathFragment, Artifact> obscuringMap = new HashMap<>();
     PathFragment pathA = PathFragment.create("a");
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     Artifact artifactA = new Artifact(PathFragment.create("a"),
                                           root);
     obscuringMap.put(pathA, artifactA);
@@ -142,7 +142,7 @@
 
   @Test
   public void testPutCatchesConflict() {
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     PathFragment pathA = PathFragment.create("a");
     Artifact artifactB = new Artifact(PathFragment.create("b"), root);
     Artifact artifactC = new Artifact(PathFragment.create("c"), root);
@@ -159,7 +159,7 @@
 
   @Test
   public void testPutReportsError() {
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     PathFragment pathA = PathFragment.create("a");
     Artifact artifactB = new Artifact(PathFragment.create("b"), root);
     Artifact artifactC = new Artifact(PathFragment.create("c"), root);
@@ -177,7 +177,7 @@
 
   @Test
   public void testPutCatchesConflictBetweenNullAndNotNull() {
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     PathFragment pathA = PathFragment.create("a");
     Artifact artifactB = new Artifact(PathFragment.create("b"), root);
     Map<PathFragment, Artifact> map = new LinkedHashMap<>();
@@ -192,7 +192,7 @@
 
   @Test
   public void testPutCatchesConflictBetweenNotNullAndNull() {
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     PathFragment pathA = PathFragment.create("a");
     Artifact artifactB = new Artifact(PathFragment.create("b"), root);
     Map<PathFragment, Artifact> map = new LinkedHashMap<>();
@@ -208,7 +208,7 @@
 
   @Test
   public void testPutIgnoresConflict() {
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     PathFragment pathA = PathFragment.create("a");
     Artifact artifactB = new Artifact(PathFragment.create("b"), root);
     Artifact artifactC = new Artifact(PathFragment.create("c"), root);
@@ -224,7 +224,7 @@
 
   @Test
   public void testPutIgnoresConflictNoListener() {
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     PathFragment pathA = PathFragment.create("a");
     Artifact artifactB = new Artifact(PathFragment.create("b"), root);
     Artifact artifactC = new Artifact(PathFragment.create("c"), root);
@@ -240,7 +240,7 @@
 
   @Test
   public void testPutIgnoresSameArtifact() {
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     PathFragment pathA = PathFragment.create("a");
     Artifact artifactB = new Artifact(PathFragment.create("b"), root);
     Artifact artifactB2 = new Artifact(PathFragment.create("b"), root);
@@ -271,7 +271,7 @@
 
   @Test
   public void testPutNoConflicts() {
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     PathFragment pathA = PathFragment.create("a");
     PathFragment pathB = PathFragment.create("b");
     PathFragment pathC = PathFragment.create("c");
@@ -325,7 +325,7 @@
 
   @Test
   public void testLegacyRunfilesStructure() {
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     PathFragment workspaceName = PathFragment.create("wsname");
     PathFragment pathB = PathFragment.create("external/repo/b");
     Artifact artifactB = new Artifact(pathB, root);
@@ -346,7 +346,7 @@
 
   @Test
   public void testRunfileAdded() {
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     PathFragment workspaceName = PathFragment.create("wsname");
     PathFragment pathB = PathFragment.create("external/repo/b");
     Artifact artifactB = new Artifact(pathB, root);
@@ -369,7 +369,7 @@
   // TODO(kchodorow): remove this once the default workspace name is always set.
   @Test
   public void testConflictWithExternal() {
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     PathFragment pathB = PathFragment.create("repo/b");
     PathFragment externalPathB = Label.EXTERNAL_PACKAGE_NAME.getRelative(pathB);
     Artifact artifactB = new Artifact(pathB, root);
@@ -393,7 +393,7 @@
 
   @Test
   public void testMergeWithSymlinks() {
-    Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(scratch.resolve("/workspace"));
     Artifact artifactA = new Artifact(PathFragment.create("a/target"), root);
     Artifact artifactB = new Artifact(PathFragment.create("b/target"), root);
     PathFragment sympathA = PathFragment.create("a/symlink");
@@ -412,7 +412,8 @@
 
   @Test
   public void testOnlyExtraMiddlemenNotConsideredEmpty() {
-    Root root = Root.middlemanRoot(scratch.resolve("execroot"), scratch.resolve("execroot/out"));
+    ArtifactRoot root =
+        ArtifactRoot.middlemanRoot(scratch.resolve("execroot"), scratch.resolve("execroot/out"));
     Artifact mm = new Artifact(PathFragment.create("a-middleman"), root);
     Runfiles runfiles = new Runfiles.Builder("TESTING").addLegacyExtraMiddleman(mm).build();
     assertThat(runfiles.isEmpty()).isFalse();
@@ -420,7 +421,8 @@
 
   @Test
   public void testMergingExtraMiddlemen() {
-    Root root = Root.middlemanRoot(scratch.resolve("execroot"), scratch.resolve("execroot/out"));
+    ArtifactRoot root =
+        ArtifactRoot.middlemanRoot(scratch.resolve("execroot"), scratch.resolve("execroot/out"));
     Artifact mm1 = new Artifact(PathFragment.create("middleman-1"), root);
     Artifact mm2 = new Artifact(PathFragment.create("middleman-2"), root);
     Runfiles runfiles1 = new Runfiles.Builder("TESTING").addLegacyExtraMiddleman(mm1).build();
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/TopLevelArtifactHelperTest.java b/src/test/java/com/google/devtools/build/lib/analysis/TopLevelArtifactHelperTest.java
index 9609bed..141982d 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/TopLevelArtifactHelperTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/TopLevelArtifactHelperTest.java
@@ -23,7 +23,7 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSortedSet;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.analysis.TopLevelArtifactHelper.ArtifactsInOutputGroup;
 import com.google.devtools.build.lib.analysis.TopLevelArtifactHelper.ArtifactsToBuild;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
@@ -45,14 +45,14 @@
   private OutputGroupInfo groupProvider;
 
   private Path path;
-  private Root root;
+  private ArtifactRoot root;
   private int artifactIdx;
 
   @Before
   public final void setRootDir() throws Exception {
     Scratch scratch = new Scratch();
     Path execRoot = scratch.getFileSystem().getPath("/");
-    root = Root.asDerivedRoot(execRoot, scratch.dir("/blaze-out"));
+    root = ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/blaze-out"));
     path = scratch.dir("/blaze-out/foo");
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/ParamFileWriteActionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/ParamFileWriteActionTest.java
index 1a541ff..ed382c4 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/actions/ParamFileWriteActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/ParamFileWriteActionTest.java
@@ -28,9 +28,9 @@
 import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType;
 import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.Executor;
 import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
 import com.google.devtools.build.lib.analysis.util.ActionTester;
 import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
@@ -50,14 +50,14 @@
 /** Tests for ParamFileWriteAction. */
 @RunWith(JUnit4.class)
 public class ParamFileWriteActionTest extends BuildViewTestCase {
-  private Root rootDir;
+  private ArtifactRoot rootDir;
   private Artifact outputArtifact;
   private Artifact treeArtifact;
 
   @Before
   public void createArtifacts() throws Exception  {
     Path execRoot = scratch.getFileSystem().getPath("/exec");
-    rootDir = Root.asDerivedRoot(execRoot, scratch.dir("/exec/out"));
+    rootDir = ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/exec/out"));
     outputArtifact = getBinArtifactWithNoOwner("destination.txt");
     FileSystemUtils.createDirectoryAndParents(outputArtifact.getPath().getParentDirectory());
     treeArtifact = createTreeArtifact("artifact/myTreeFileArtifact");
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactActionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactActionTest.java
index 96f5afe..5a54a9e0 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactActionTest.java
@@ -31,9 +31,9 @@
 import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType;
 import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.BaseSpawn;
 import com.google.devtools.build.lib.actions.Executor;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.actions.Spawn;
 import com.google.devtools.build.lib.actions.SpawnActionContext;
 import com.google.devtools.build.lib.actions.cache.Md5Digest;
@@ -106,12 +106,12 @@
     }
   };
 
-  private Root root;
+  private ArtifactRoot root;
 
   @Before
   public void setRootDir() throws Exception  {
     Path execRoot = scratch.getFileSystem().getPath("/exec");
-    root = Root.asDerivedRoot(execRoot, scratch.dir("/exec/out"));
+    root = ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/exec/out"));
   }
 
   @Test
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplateTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplateTest.java
index b325e3b..a13091d 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplateTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplateTest.java
@@ -24,7 +24,7 @@
 import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType;
 import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
 import com.google.devtools.build.lib.analysis.actions.SpawnActionTemplate.OutputPathMapper;
 import com.google.devtools.build.lib.testutil.Scratch;
@@ -48,13 +48,13 @@
     }
   };
 
-  private Root root;
+  private ArtifactRoot root;
 
   @Before
   public void setRootDir() throws Exception  {
     Scratch scratch = new Scratch();
     Path execRoot = scratch.getFileSystem().getPath("/");
-    root = Root.asDerivedRoot(execRoot, scratch.dir("/exec/root"));
+    root = ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/exec/root"));
   }
 
   @Test
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/TemplateExpansionActionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/TemplateExpansionActionTest.java
index 2528e3b..3f6e62d 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/actions/TemplateExpansionActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/TemplateExpansionActionTest.java
@@ -24,8 +24,8 @@
 import com.google.devtools.build.lib.actions.ActionInputPrefetcher;
 import com.google.devtools.build.lib.actions.ActionKeyContext;
 import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.Executor;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.analysis.BlazeDirectories;
 import com.google.devtools.build.lib.analysis.ServerDirectories;
 import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution;
@@ -52,7 +52,7 @@
   private static final String TEMPLATE = Joiner.on('\n').join("key=%key%", "value=%value%");
   private static final String SPECIAL_CHARS = "Š©±½_strøget";
 
-  private Root outputRoot;
+  private ArtifactRoot outputRoot;
   private Artifact inputArtifact;
   private Artifact outputArtifact;
   private Path output;
@@ -77,8 +77,9 @@
   }
 
   private void createArtifacts(String template) throws Exception {
-    Root workspace = Root.asSourceRoot(scratch.dir("/workspace"));
-    outputRoot = Root.asDerivedRoot(scratch.dir("/workspace"), scratch.dir("/workspace/out"));
+    ArtifactRoot workspace = ArtifactRoot.asSourceRoot(scratch.dir("/workspace"));
+    outputRoot =
+        ArtifactRoot.asDerivedRoot(scratch.dir("/workspace"), scratch.dir("/workspace/out"));
     Path input = scratch.overwriteFile("/workspace/input.txt", StandardCharsets.UTF_8, template);
     inputArtifact = new Artifact(input, workspace);
     output = scratch.resolve("/workspace/out/destination.txt");
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java
index 8e3f755..1a5c6ea 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java
@@ -29,11 +29,11 @@
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.ArtifactFactory;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.ExecutionStrategy;
 import com.google.devtools.build.lib.actions.MiddlemanFactory;
 import com.google.devtools.build.lib.actions.MutableActionGraph;
 import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
 import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
 import com.google.devtools.build.lib.analysis.BlazeDirectories;
@@ -120,22 +120,22 @@
     }
 
     @Override
-    public Artifact getDerivedArtifact(PathFragment rootRelativePath, Root root) {
+    public Artifact getDerivedArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
       return original.getDerivedArtifact(rootRelativePath, root);
     }
 
     @Override
-    public Artifact getConstantMetadataArtifact(PathFragment rootRelativePath, Root root) {
+    public Artifact getConstantMetadataArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
       return original.getConstantMetadataArtifact(rootRelativePath, root);
     }
 
     @Override
-    public Artifact getTreeArtifact(PathFragment rootRelativePath, Root root) {
+    public Artifact getTreeArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
       return null;
     }
 
     @Override
-    public Artifact getFilesetArtifact(PathFragment rootRelativePath, Root root) {
+    public Artifact getFilesetArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
       return original.getFilesetArtifact(rootRelativePath, root);
     }
 
@@ -326,12 +326,12 @@
     }
 
     @Override
-    public Artifact getConstantMetadataArtifact(PathFragment rootRelativePath, Root root) {
+    public Artifact getConstantMetadataArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
       return null;
     }
 
     @Override
-    public Artifact getTreeArtifact(PathFragment rootRelativePath, Root root) {
+    public Artifact getTreeArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
       return null;
     }
 
@@ -366,12 +366,12 @@
     }
 
     @Override
-    public Artifact getFilesetArtifact(PathFragment rootRelativePath, Root root) {
+    public Artifact getFilesetArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
       return null;
     }
 
     @Override
-    public Artifact getDerivedArtifact(PathFragment rootRelativePath, Root root) {
+    public Artifact getDerivedArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
       return null;
     }
 
@@ -462,7 +462,7 @@
 
     Set<String> files = new LinkedHashSet<>();
     for (Artifact artifact : artifacts) {
-      Root root = artifact.getRoot();
+      ArtifactRoot root = artifact.getRoot();
       if (root.isSourceRoot()) {
         files.add("src " + artifact.getRootRelativePath());
       } else {
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
index 457d184..a448942 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
@@ -36,13 +36,13 @@
 import com.google.devtools.build.lib.actions.ActionKeyContext;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.CommandLineExpansionException;
 import com.google.devtools.build.lib.actions.MapBasedActionGraph;
 import com.google.devtools.build.lib.actions.MiddlemanFactory;
 import com.google.devtools.build.lib.actions.MutableActionGraph;
 import com.google.devtools.build.lib.actions.ResourceManager;
 import com.google.devtools.build.lib.actions.ResourceSet;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
 import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
 import com.google.devtools.build.lib.analysis.AnalysisUtils;
@@ -970,12 +970,12 @@
         .isSameAs(getGeneratingActionForLabel(labelA));
   }
 
-  protected Artifact getSourceArtifact(PathFragment rootRelativePath, Root root) {
+  protected Artifact getSourceArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
     return view.getArtifactFactory().getSourceArtifact(rootRelativePath, root);
   }
 
   protected Artifact getSourceArtifact(String name) {
-    return getSourceArtifact(PathFragment.create(name), Root.asSourceRoot(rootDirectory));
+    return getSourceArtifact(PathFragment.create(name), ArtifactRoot.asSourceRoot(rootDirectory));
   }
 
   /**
@@ -985,7 +985,7 @@
    * #getBinArtifactWithNoOwner} or {@link #getGenfilesArtifactWithNoOwner} should be used instead.
    */
   protected Artifact getDerivedArtifact(
-      PathFragment rootRelativePath, Root root, ArtifactOwner owner) {
+      PathFragment rootRelativePath, ArtifactRoot root, ArtifactOwner owner) {
     return view.getArtifactFactory().getDerivedArtifact(rootRelativePath, root, owner);
   }
 
@@ -993,10 +993,10 @@
    * Gets a derived Artifact for testing with path of the form
    * root/owner.getPackageFragment()/packageRelativePath.
    *
-   * @see #getDerivedArtifact(PathFragment, Root, ArtifactOwner)
+   * @see #getDerivedArtifact(PathFragment, ArtifactRoot, ArtifactOwner)
    */
-  private Artifact getPackageRelativeDerivedArtifact(String packageRelativePath, Root root,
-      ArtifactOwner owner) {
+  private Artifact getPackageRelativeDerivedArtifact(
+      String packageRelativePath, ArtifactRoot root, ArtifactOwner owner) {
     return getDerivedArtifact(
         owner.getLabel().getPackageFragment().getRelative(packageRelativePath),
         root, owner);
@@ -1708,12 +1708,12 @@
     }
 
     @Override
-    public Artifact getConstantMetadataArtifact(PathFragment rootRelativePath, Root root) {
+    public Artifact getConstantMetadataArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
       throw new UnsupportedOperationException();
     }
 
     @Override
-    public Artifact getTreeArtifact(PathFragment rootRelativePath, Root root) {
+    public Artifact getTreeArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
       throw new UnsupportedOperationException();
     }
 
@@ -1748,12 +1748,12 @@
     }
 
     @Override
-    public Artifact getFilesetArtifact(PathFragment rootRelativePath, Root root) {
+    public Artifact getFilesetArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
       throw new UnsupportedOperationException();
     }
 
     @Override
-    public Artifact getDerivedArtifact(PathFragment rootRelativePath, Root root) {
+    public Artifact getDerivedArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
       throw new UnsupportedOperationException();
     }
 
@@ -1925,7 +1925,7 @@
     Rule associatedRule = target.getTarget().getAssociatedRule();
     RepositoryName repository = associatedRule.getRepository();
 
-    Root root;
+    ArtifactRoot root;
     if (associatedRule.hasBinaryOutput()) {
       root = configuration.getBinDirectory(repository);
     } else {
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/ConfigurationTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/ConfigurationTestCase.java
index c142337..7953c33 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/ConfigurationTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/ConfigurationTestCase.java
@@ -20,7 +20,7 @@
 import com.google.common.collect.ImmutableSortedSet;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.actions.ActionKeyContext;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.analysis.BlazeDirectories;
 import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
 import com.google.devtools.build.lib.analysis.ServerDirectories;
@@ -201,7 +201,7 @@
 
   public void assertConfigurationsHaveUniqueOutputDirectories(
       BuildConfigurationCollection configCollection) throws Exception {
-    Map<Root, BuildConfiguration> outputPaths = new HashMap<>();
+    Map<ArtifactRoot, BuildConfiguration> outputPaths = new HashMap<>();
     for (BuildConfiguration config : configCollection.getTargetConfigurations()) {
       if (config.isActionsEnabled()) {
         BuildConfiguration otherConfig = outputPaths.get(
diff --git a/src/test/java/com/google/devtools/build/lib/exec/FilesetManifestTest.java b/src/test/java/com/google/devtools/build/lib/exec/FilesetManifestTest.java
index 4099d2e..a71ba03 100644
--- a/src/test/java/com/google/devtools/build/lib/exec/FilesetManifestTest.java
+++ b/src/test/java/com/google/devtools/build/lib/exec/FilesetManifestTest.java
@@ -20,7 +20,7 @@
 import static org.junit.Assert.fail;
 
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.vfs.FileSystem;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
 import com.google.devtools.build.lib.vfs.Path;
@@ -58,7 +58,7 @@
     // See AnalysisUtils for the mapping from "foo" to "_foo/MANIFEST".
     scratchFile("/root/_foo/MANIFEST");
 
-    Artifact artifact = new Artifact(fs.getPath("/root/foo"), Root.asSourceRoot(execRoot));
+    Artifact artifact = new Artifact(fs.getPath("/root/foo"), ArtifactRoot.asSourceRoot(execRoot));
     FilesetManifest manifest =
         FilesetManifest.parseManifestFile(artifact, execRoot, "workspace", IGNORE);
     assertThat(manifest.getEntries()).isEmpty();
@@ -72,7 +72,8 @@
         "workspace/bar /dir/file",
         "<some digest>");
 
-    Root outputRoot = Root.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
+    ArtifactRoot outputRoot =
+        ArtifactRoot.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
     Artifact artifact = new Artifact(fs.getPath("/root/out/foo"), outputRoot);
     FilesetManifest manifest =
         FilesetManifest.parseManifestFile(artifact, execRoot, "workspace", IGNORE);
@@ -90,7 +91,8 @@
         "workspace/baz /dir/file",
         "<some digest>");
 
-    Root outputRoot = Root.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
+    ArtifactRoot outputRoot =
+        ArtifactRoot.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
     Artifact artifact = new Artifact(fs.getPath("/root/out/foo"), outputRoot);
     FilesetManifest manifest =
         FilesetManifest.parseManifestFile(artifact, execRoot, "workspace", IGNORE);
@@ -108,7 +110,8 @@
         "workspace/bar /some",
         "<some digest>");
 
-    Root outputRoot = Root.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
+    ArtifactRoot outputRoot =
+        ArtifactRoot.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
     Artifact artifact = new Artifact(fs.getPath("/root/out/foo"), outputRoot);
     FilesetManifest manifest =
         FilesetManifest.parseManifestFile(artifact, execRoot, "workspace", IGNORE);
@@ -125,7 +128,8 @@
         "workspace/bar ", // <-- Note the trailing whitespace!
         "<some digest>");
 
-    Root outputRoot = Root.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
+    ArtifactRoot outputRoot =
+        ArtifactRoot.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
     Artifact artifact = new Artifact(fs.getPath("/root/out/foo"), outputRoot);
     FilesetManifest manifest =
         FilesetManifest.parseManifestFile(artifact, execRoot, "workspace", IGNORE);
@@ -140,7 +144,8 @@
         "notworkspace/bar /foo/bar",
         "<some digest>");
 
-    Root outputRoot = Root.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
+    ArtifactRoot outputRoot =
+        ArtifactRoot.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
     Artifact artifact = new Artifact(fs.getPath("/root/out/foo"), outputRoot);
     try {
       FilesetManifest.parseManifestFile(artifact, execRoot, "workspace", IGNORE);
@@ -162,7 +167,8 @@
         "workspace/foo /foo/bar",
         "<some digest>");
 
-    Root outputRoot = Root.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
+    ArtifactRoot outputRoot =
+        ArtifactRoot.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
     Artifact artifact = new Artifact(fs.getPath("/root/out/foo"), outputRoot);
     try {
       FilesetManifest.parseManifestFile(artifact, execRoot, "workspace", ERROR);
@@ -182,7 +188,8 @@
         "workspace/foo /foo/bar",
         "<some digest>");
 
-    Root outputRoot = Root.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
+    ArtifactRoot outputRoot =
+        ArtifactRoot.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
     Artifact artifact = new Artifact(fs.getPath("/root/out/foo"), outputRoot);
     FilesetManifest manifest =
         FilesetManifest.parseManifestFile(artifact, execRoot, "workspace", IGNORE);
@@ -200,7 +207,8 @@
         "workspace/foo /foo/bar",
         "<some digest>");
 
-    Root outputRoot = Root.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
+    ArtifactRoot outputRoot =
+        ArtifactRoot.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
     Artifact artifact = new Artifact(fs.getPath("/root/out/foo"), outputRoot);
     FilesetManifest manifest =
         FilesetManifest.parseManifestFile(artifact, execRoot, "workspace", RESOLVE);
@@ -218,7 +226,8 @@
         "workspace/bar foo",
         "<some digest>");
 
-    Root outputRoot = Root.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
+    ArtifactRoot outputRoot =
+        ArtifactRoot.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
     Artifact artifact = new Artifact(fs.getPath("/root/out/foo"), outputRoot);
     try {
       FilesetManifest.parseManifestFile(artifact, execRoot, "workspace", RESOLVE);
@@ -242,7 +251,8 @@
         "workspace/bar /baz",
         "<some digest>");
 
-    Root outputRoot = Root.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
+    ArtifactRoot outputRoot =
+        ArtifactRoot.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
     Artifact artifact = new Artifact(fs.getPath("/root/out/foo"), outputRoot);
     FilesetManifest manifest =
         FilesetManifest.parseManifestFile(artifact, execRoot, "workspace", IGNORE);
diff --git a/src/test/java/com/google/devtools/build/lib/exec/SpawnInputExpanderTest.java b/src/test/java/com/google/devtools/build/lib/exec/SpawnInputExpanderTest.java
index 71359fd..9e14fac 100644
--- a/src/test/java/com/google/devtools/build/lib/exec/SpawnInputExpanderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/exec/SpawnInputExpanderTest.java
@@ -20,8 +20,8 @@
 import com.google.devtools.build.lib.actions.ActionInput;
 import com.google.devtools.build.lib.actions.ActionInputHelper;
 import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.EmptyRunfilesSupplier;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.actions.RunfilesSupplier;
 import com.google.devtools.build.lib.analysis.Runfiles;
 import com.google.devtools.build.lib.analysis.RunfilesSupplierImpl;
@@ -76,7 +76,7 @@
   @Test
   public void testRunfilesSingleFile() throws Exception {
     Artifact artifact =
-        new Artifact(fs.getPath("/root/dir/file"), Root.asSourceRoot(fs.getPath("/root")));
+        new Artifact(fs.getPath("/root/dir/file"), ArtifactRoot.asSourceRoot(fs.getPath("/root")));
     Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(artifact).build();
     RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
     FakeActionInputFileCache mockCache = new FakeActionInputFileCache();
@@ -91,7 +91,7 @@
   @Test
   public void testRunfilesDirectoryStrict() throws Exception {
     Artifact artifact =
-        new Artifact(fs.getPath("/root/dir/file"), Root.asSourceRoot(fs.getPath("/root")));
+        new Artifact(fs.getPath("/root/dir/file"), ArtifactRoot.asSourceRoot(fs.getPath("/root")));
     Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(artifact).build();
     RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
     FakeActionInputFileCache mockCache = new FakeActionInputFileCache();
@@ -108,7 +108,7 @@
   @Test
   public void testRunfilesDirectoryNonStrict() throws Exception {
     Artifact artifact =
-        new Artifact(fs.getPath("/root/dir/file"), Root.asSourceRoot(fs.getPath("/root")));
+        new Artifact(fs.getPath("/root/dir/file"), ArtifactRoot.asSourceRoot(fs.getPath("/root")));
     Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(artifact).build();
     RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
     FakeActionInputFileCache mockCache = new FakeActionInputFileCache();
@@ -124,9 +124,9 @@
   @Test
   public void testRunfilesTwoFiles() throws Exception {
     Artifact artifact1 =
-        new Artifact(fs.getPath("/root/dir/file"), Root.asSourceRoot(fs.getPath("/root")));
+        new Artifact(fs.getPath("/root/dir/file"), ArtifactRoot.asSourceRoot(fs.getPath("/root")));
     Artifact artifact2 =
-        new Artifact(fs.getPath("/root/dir/baz"), Root.asSourceRoot(fs.getPath("/root")));
+        new Artifact(fs.getPath("/root/dir/baz"), ArtifactRoot.asSourceRoot(fs.getPath("/root")));
     Runfiles runfiles = new Runfiles.Builder("workspace")
         .addArtifact(artifact1)
         .addArtifact(artifact2)
@@ -147,7 +147,7 @@
   @Test
   public void testRunfilesSymlink() throws Exception {
     Artifact artifact =
-        new Artifact(fs.getPath("/root/dir/file"), Root.asSourceRoot(fs.getPath("/root")));
+        new Artifact(fs.getPath("/root/dir/file"), ArtifactRoot.asSourceRoot(fs.getPath("/root")));
     Runfiles runfiles = new Runfiles.Builder("workspace")
         .addSymlink(PathFragment.create("symlink"), artifact).build();
     RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
@@ -163,7 +163,7 @@
   @Test
   public void testRunfilesRootSymlink() throws Exception {
     Artifact artifact =
-        new Artifact(fs.getPath("/root/dir/file"), Root.asSourceRoot(fs.getPath("/root")));
+        new Artifact(fs.getPath("/root/dir/file"), ArtifactRoot.asSourceRoot(fs.getPath("/root")));
     Runfiles runfiles = new Runfiles.Builder("workspace")
         .addRootSymlink(PathFragment.create("symlink"), artifact).build();
     RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
@@ -185,7 +185,8 @@
     // See AnalysisUtils for the mapping from "foo" to "_foo/MANIFEST".
     scratchFile("/root/out/_foo/MANIFEST");
 
-    Root outputRoot = Root.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
+    ArtifactRoot outputRoot =
+        ArtifactRoot.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
     Artifact artifact = new Artifact(fs.getPath("/root/out/foo"), outputRoot);
     expander.parseFilesetManifest(inputMappings, artifact, "workspace");
     assertThat(inputMappings).isEmpty();
@@ -199,7 +200,8 @@
         "workspace/bar /dir/file",
         "<some digest>");
 
-    Root outputRoot = Root.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
+    ArtifactRoot outputRoot =
+        ArtifactRoot.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
     Artifact artifact = new Artifact(fs.getPath("/root/out/foo"), outputRoot);
     expander.parseFilesetManifest(inputMappings, artifact, "workspace");
     assertThat(inputMappings).hasSize(1);
@@ -217,7 +219,8 @@
         "workspace/baz /dir/file",
         "<some digest>");
 
-    Root outputRoot = Root.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
+    ArtifactRoot outputRoot =
+        ArtifactRoot.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
     Artifact artifact = new Artifact(fs.getPath("/root/out/foo"), outputRoot);
     expander.parseFilesetManifest(inputMappings, artifact, "workspace");
     assertThat(inputMappings).hasSize(2);
@@ -235,7 +238,8 @@
         "workspace/bar /some",
         "<some digest>");
 
-    Root outputRoot = Root.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
+    ArtifactRoot outputRoot =
+        ArtifactRoot.asDerivedRoot(fs.getPath("/root"), fs.getPath("/root/out"));
     Artifact artifact = new Artifact(fs.getPath("/root/out/foo"), outputRoot);
     expander.parseFilesetManifest(inputMappings, artifact, "workspace");
     assertThat(inputMappings).hasSize(1);
diff --git a/src/test/java/com/google/devtools/build/lib/remote/TreeNodeRepositoryTest.java b/src/test/java/com/google/devtools/build/lib/remote/TreeNodeRepositoryTest.java
index 8c4f35e..48953ce 100644
--- a/src/test/java/com/google/devtools/build/lib/remote/TreeNodeRepositoryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/remote/TreeNodeRepositoryTest.java
@@ -20,7 +20,7 @@
 import com.google.devtools.build.lib.actions.ActionInputFileCache;
 import com.google.devtools.build.lib.actions.ActionInputHelper;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.clock.BlazeClock;
 import com.google.devtools.build.lib.exec.SingleBuildFileCache;
 import com.google.devtools.build.lib.remote.TreeNodeRepository.TreeNode;
@@ -46,14 +46,14 @@
   private Scratch scratch;
   private DigestUtil digestUtil;
   private Path execRoot;
-  private Root rootDir;
+  private ArtifactRoot rootDir;
 
   @Before
   public final void setRootDir() throws Exception {
     digestUtil = new DigestUtil(HashFunction.SHA256);
     scratch = new Scratch(new InMemoryFileSystem(BlazeClock.instance(), HashFunction.SHA256));
     execRoot = scratch.getFileSystem().getPath("/exec/root");
-    rootDir = Root.asSourceRoot(scratch.dir("/exec/root"));
+    rootDir = ArtifactRoot.asSourceRoot(scratch.dir("/exec/root"));
   }
 
   private TreeNodeRepository createTestTreeNodeRepository() {
diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/ResourceTestBase.java b/src/test/java/com/google/devtools/build/lib/rules/android/ResourceTestBase.java
index f86a574..37bcf0d 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/android/ResourceTestBase.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/android/ResourceTestBase.java
@@ -21,7 +21,7 @@
 import com.google.common.collect.Multimap;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
 import com.google.devtools.build.lib.packages.AbstractRuleErrorConsumer;
@@ -156,13 +156,13 @@
 
   public FakeRuleErrorConsumer errorConsumer;
   public FileSystem fileSystem;
-  public Root root;
+  public ArtifactRoot root;
 
   @Before
   public void setup() {
     errorConsumer = new FakeRuleErrorConsumer();
     fileSystem = new InMemoryFileSystem();
-    root = Root.asSourceRoot(fileSystem.getRootDirectory());
+    root = ArtifactRoot.asSourceRoot(fileSystem.getRootDirectory());
   }
 
   @After
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CompileCommandLineTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CompileCommandLineTest.java
index 99aa8a7..1e9b36d 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CompileCommandLineTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CompileCommandLineTest.java
@@ -18,7 +18,7 @@
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableSet;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
 import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
 import com.google.devtools.build.lib.rules.cpp.CompileCommandLine.Builder;
@@ -42,7 +42,7 @@
   private Artifact scratchArtifact(String s) {
     Path execRoot = outputBase.getRelative("exec");
     Path outputRoot = execRoot.getRelative("root");
-    Root root = Root.asDerivedRoot(execRoot, outputRoot);
+    ArtifactRoot root = ArtifactRoot.asDerivedRoot(execRoot, outputRoot);
     try {
       return new Artifact(scratch.overwriteFile(outputRoot.getRelative(s).toString()), root);
     } catch (IOException e) {
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java
index 6107747..703c3ff 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java
@@ -30,8 +30,8 @@
 import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType;
 import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.ResourceSet;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
 import com.google.devtools.build.lib.analysis.ConfiguredTarget;
 import com.google.devtools.build.lib.analysis.RuleContext;
@@ -82,7 +82,7 @@
           }
 
           @Override
-          public Artifact getDerivedArtifact(PathFragment rootRelativePath, Root root) {
+          public Artifact getDerivedArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
             return CppLinkActionTest.this.getDerivedArtifact(
                 rootRelativePath, root, ActionsTestUtil.NULL_ARTIFACT_OWNER);
           }
@@ -533,7 +533,7 @@
   private Artifact scratchArtifact(String s) {
     Path execRoot = outputBase.getRelative("exec");
     Path outputRoot = execRoot.getRelative("out");
-    Root root = Root.asDerivedRoot(execRoot, outputRoot);
+    ArtifactRoot root = ArtifactRoot.asDerivedRoot(execRoot, outputRoot);
     try {
       return new Artifact(scratch.overwriteFile(outputRoot.getRelative(s).toString()), root);
     } catch (IOException e) {
@@ -673,7 +673,7 @@
     Path path = execRoot.getRelative(execPath);
     return new SpecialArtifact(
         path,
-        Root.asDerivedRoot(execRoot, execRoot.getRelative("out")),
+        ArtifactRoot.asDerivedRoot(execRoot, execRoot.getRelative("out")),
         execPath,
         ArtifactOwner.NULL_OWNER,
         SpecialArtifactType.TREE);
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CreateIncSymlinkActionTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CreateIncSymlinkActionTest.java
index b7ea510..273d986 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CreateIncSymlinkActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CreateIncSymlinkActionTest.java
@@ -20,7 +20,7 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.actions.ActionKeyContext;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.testutil.FoundationTestCase;
 import com.google.devtools.build.lib.vfs.Path;
 import com.google.devtools.build.lib.vfs.PathFragment;
@@ -39,7 +39,7 @@
 
   @Test
   public void testDifferentOrderSameActionKey() throws Exception {
-    Root root = Root.asDerivedRoot(rootDirectory, rootDirectory.getRelative("out"));
+    ArtifactRoot root = ArtifactRoot.asDerivedRoot(rootDirectory, rootDirectory.getRelative("out"));
     Artifact a = new Artifact(PathFragment.create("a"), root);
     Artifact b = new Artifact(PathFragment.create("b"), root);
     Artifact c = new Artifact(PathFragment.create("c"), root);
@@ -59,7 +59,7 @@
 
   @Test
   public void testDifferentTargetsDifferentActionKey() throws Exception {
-    Root root = Root.asDerivedRoot(rootDirectory, rootDirectory.getRelative("out"));
+    ArtifactRoot root = ArtifactRoot.asDerivedRoot(rootDirectory, rootDirectory.getRelative("out"));
     Artifact a = new Artifact(PathFragment.create("a"), root);
     Artifact b = new Artifact(PathFragment.create("b"), root);
     CreateIncSymlinkAction action1 = new CreateIncSymlinkAction(NULL_ACTION_OWNER,
@@ -75,7 +75,7 @@
 
   @Test
   public void testDifferentSymlinksDifferentActionKey() throws Exception {
-    Root root = Root.asDerivedRoot(rootDirectory, rootDirectory.getRelative("out"));
+    ArtifactRoot root = ArtifactRoot.asDerivedRoot(rootDirectory, rootDirectory.getRelative("out"));
     Artifact a = new Artifact(PathFragment.create("a"), root);
     Artifact b = new Artifact(PathFragment.create("b"), root);
     CreateIncSymlinkAction action1 = new CreateIncSymlinkAction(NULL_ACTION_OWNER,
@@ -93,7 +93,7 @@
   public void testExecute() throws Exception {
     Path outputDir = rootDirectory.getRelative("out");
     outputDir.createDirectory();
-    Root root = Root.asDerivedRoot(rootDirectory, outputDir);
+    ArtifactRoot root = ArtifactRoot.asDerivedRoot(rootDirectory, outputDir);
     Path symlink = rootDirectory.getRelative("out/a");
     Artifact a = new Artifact(symlink, root);
     Artifact b = new Artifact(PathFragment.create("b"), root);
@@ -110,7 +110,7 @@
   public void testFileRemoved() throws Exception {
     Path outputDir = rootDirectory.getRelative("out");
     outputDir.createDirectory();
-    Root root = Root.asDerivedRoot(rootDirectory, outputDir);
+    ArtifactRoot root = ArtifactRoot.asDerivedRoot(rootDirectory, outputDir);
     Path symlink = rootDirectory.getRelative("out/subdir/a");
     Artifact a = new Artifact(symlink, root);
     Artifact b = new Artifact(PathFragment.create("b"), root);
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/J2ObjcSourceTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/J2ObjcSourceTest.java
index 043476e..0486cd3 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/J2ObjcSourceTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/J2ObjcSourceTest.java
@@ -17,7 +17,7 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.testing.EqualsTester;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.testutil.Scratch;
 import com.google.devtools.build.lib.vfs.Path;
@@ -32,13 +32,13 @@
  */
 @RunWith(JUnit4.class)
 public class J2ObjcSourceTest {
-  private Root rootDir;
+  private ArtifactRoot rootDir;
 
   @Before
   public final void setRootDir() throws Exception  {
     Scratch scratch = new Scratch();
     Path execRoot = scratch.getFileSystem().getPath("/exec");
-    rootDir = Root.asDerivedRoot(execRoot, scratch.dir("/exec/root"));
+    rootDir = ArtifactRoot.asDerivedRoot(execRoot, scratch.dir("/exec/root"));
   }
 
   @Test
diff --git a/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilderTest.java b/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilderTest.java
index 44cc3f8..08d6f9c 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilderTest.java
@@ -23,7 +23,7 @@
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.util.LabelArtifactOwner;
 import com.google.devtools.build.lib.analysis.FilesToRunProvider;
 import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
@@ -45,9 +45,9 @@
 public class ProtoCompileActionBuilderTest {
 
   private static final InMemoryFileSystem FILE_SYSTEM = new InMemoryFileSystem();
-  private final Root root = Root.asSourceRoot(FILE_SYSTEM.getPath("/"));
-  private final Root derivedRoot =
-      Root.asDerivedRoot(FILE_SYSTEM.getPath("/"), FILE_SYSTEM.getPath("/out"));
+  private final ArtifactRoot root = ArtifactRoot.asSourceRoot(FILE_SYSTEM.getPath("/"));
+  private final ArtifactRoot derivedRoot =
+      ArtifactRoot.asDerivedRoot(FILE_SYSTEM.getPath("/"), FILE_SYSTEM.getPath("/out"));
 
   @Test
   public void commandLine_basic() throws Exception {
diff --git a/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java b/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java
index 81b4328..b522705 100644
--- a/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java
@@ -26,8 +26,8 @@
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.EventReportingArtifacts;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.analysis.BlazeDirectories;
 import com.google.devtools.build.lib.analysis.ServerDirectories;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
@@ -520,7 +520,7 @@
 
   private Artifact makeArtifact(String pathString) {
     Path path = outputBase.getRelative(PathFragment.create(pathString));
-    return new Artifact(path, Root.asSourceRoot(outputBase));
+    return new Artifact(path, ArtifactRoot.asSourceRoot(outputBase));
   }
 
   @Test
diff --git a/src/test/java/com/google/devtools/build/lib/runtime/ExperimentalStateTrackerTest.java b/src/test/java/com/google/devtools/build/lib/runtime/ExperimentalStateTrackerTest.java
index b9133f3..b7db0b3 100644
--- a/src/test/java/com/google/devtools/build/lib/runtime/ExperimentalStateTrackerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/runtime/ExperimentalStateTrackerTest.java
@@ -31,7 +31,7 @@
 import com.google.devtools.build.lib.actions.ActionStartedEvent;
 import com.google.devtools.build.lib.actions.ActionStatusMessage;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.analysis.ConfiguredTarget;
 import com.google.devtools.build.lib.bazel.repository.downloader.DownloadProgressEvent;
 import com.google.devtools.build.lib.buildeventstream.AnnounceBuildEventTransportsEvent;
@@ -68,7 +68,7 @@
 
   private Action mockAction(String progressMessage, String primaryOutput) {
     Path path = outputBase.getRelative(PathFragment.create(primaryOutput));
-    Artifact artifact = new Artifact(path, Root.asSourceRoot(outputBase));
+    Artifact artifact = new Artifact(path, ArtifactRoot.asSourceRoot(outputBase));
 
     Action action = Mockito.mock(Action.class);
     when(action.getProgressMessage()).thenReturn(progressMessage);
@@ -473,7 +473,7 @@
 
     ManualClock clock = new ManualClock();
     Path path = outputBase.getRelative(PathFragment.create(primaryOutput));
-    Artifact artifact = new Artifact(path, Root.asSourceRoot(outputBase));
+    Artifact artifact = new Artifact(path, ArtifactRoot.asSourceRoot(outputBase));
     ActionExecutionMetadata actionMetadata = Mockito.mock(ActionExecutionMetadata.class);
     when(actionMetadata.getOwner()).thenReturn(Mockito.mock(ActionOwner.class));
     when(actionMetadata.getPrimaryOutput()).thenReturn(artifact);
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ActionTemplateExpansionFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ActionTemplateExpansionFunctionTest.java
index 8e55e34..f122174 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/ActionTemplateExpansionFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/ActionTemplateExpansionFunctionTest.java
@@ -30,8 +30,8 @@
 import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
 import com.google.devtools.build.lib.actions.ArtifactPrefixConflictException;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
 import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
 import com.google.devtools.build.lib.analysis.actions.SpawnActionTemplate;
@@ -209,7 +209,7 @@
     Path fullPath = rootDirectory.getRelative(execPath);
     return new SpecialArtifact(
         fullPath,
-        Root.asDerivedRoot(rootDirectory, rootDirectory.getRelative("out")),
+        ArtifactRoot.asDerivedRoot(rootDirectory, rootDirectory.getRelative("out")),
         execPath,
         ArtifactOwner.NULL_OWNER,
         SpecialArtifactType.TREE);
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 aba2931..339ad4e 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
@@ -31,8 +31,8 @@
 import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
 import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType;
 import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.MissingInputFileException;
-import com.google.devtools.build.lib.actions.Root;
 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.events.NullEventHandler;
@@ -245,7 +245,7 @@
   }
 
   private Artifact createSourceArtifact(String path) {
-    return new Artifact(PathFragment.create(path), Root.asSourceRoot(root));
+    return new Artifact(PathFragment.create(path), ArtifactRoot.asSourceRoot(root));
   }
 
   private Artifact createDerivedArtifact(String path) {
@@ -253,13 +253,17 @@
     Path fullPath = root.getRelative(execPath);
     Artifact output =
         new Artifact(
-            fullPath, Root.asDerivedRoot(root, root.getRelative("out")), execPath, ALL_OWNER);
+            fullPath,
+            ArtifactRoot.asDerivedRoot(root, root.getRelative("out")),
+            execPath,
+            ALL_OWNER);
     actions.add(new DummyAction(ImmutableList.<Artifact>of(), output));
     return output;
   }
 
   private Artifact createMiddlemanArtifact(String path) {
-    Root middlemanRoot = Root.middlemanRoot(middlemanPath, middlemanPath.getRelative("out"));
+    ArtifactRoot middlemanRoot =
+        ArtifactRoot.middlemanRoot(middlemanPath, middlemanPath.getRelative("out"));
     Path fullPath = middlemanRoot.getPath().getRelative(path);
     return new Artifact(
         fullPath, middlemanRoot, fullPath.relativeTo(middlemanRoot.getExecRoot()), ALL_OWNER);
@@ -276,7 +280,7 @@
     Path fullPath = root.getRelative(execPath);
     return new SpecialArtifact(
         fullPath,
-        Root.asDerivedRoot(root, root.getRelative("out")),
+        ArtifactRoot.asDerivedRoot(root, root.getRelative("out")),
         execPath,
         ALL_OWNER,
         SpecialArtifactType.TREE);
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunctionTest.java
index 90ed181..2671226 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunctionTest.java
@@ -25,11 +25,11 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.FilesetOutputSymlink;
 import com.google.devtools.build.lib.actions.FilesetTraversalParams;
 import com.google.devtools.build.lib.actions.FilesetTraversalParams.PackageBoundaryMode;
 import com.google.devtools.build.lib.actions.FilesetTraversalParamsFactory;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.analysis.BlazeDirectories;
 import com.google.devtools.build.lib.analysis.ServerDirectories;
 import com.google.devtools.build.lib.cmdline.Label;
@@ -129,7 +129,7 @@
   }
 
   private Artifact getSourceArtifact(String path) throws Exception {
-    return new Artifact(PathFragment.create(path), Root.asSourceRoot(rootDirectory));
+    return new Artifact(PathFragment.create(path), ArtifactRoot.asSourceRoot(rootDirectory));
   }
 
   private Artifact createSourceArtifact(String path) throws Exception {
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 5005910..01ed4fd 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
@@ -29,7 +29,7 @@
 import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType;
 import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.util.TestAction;
 import com.google.devtools.build.lib.analysis.BlazeDirectories;
 import com.google.devtools.build.lib.analysis.ServerDirectories;
@@ -608,14 +608,14 @@
     Path outputPath = fs.getPath("/bin");
     outputPath.createDirectory();
     return new Artifact(
-        outputPath.getRelative(relPath), Root.asDerivedRoot(fs.getPath("/"), outputPath));
+        outputPath.getRelative(relPath), ArtifactRoot.asDerivedRoot(fs.getPath("/"), outputPath));
   }
 
   private Artifact createTreeArtifact(String relPath) throws IOException {
     Path outputDir = fs.getPath("/bin");
     Path outputPath = outputDir.getRelative(relPath);
     outputDir.createDirectory();
-    Root derivedRoot = Root.asDerivedRoot(fs.getPath("/"), outputDir);
+    ArtifactRoot derivedRoot = ArtifactRoot.asDerivedRoot(fs.getPath("/"), outputDir);
     return new SpecialArtifact(outputPath, derivedRoot,
         derivedRoot.getExecPath().getRelative(outputPath.relativeTo(derivedRoot.getPath())),
         ArtifactOwner.NULL_OWNER, SpecialArtifactType.TREE);
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java
index bb54b99..1779162 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java
@@ -28,8 +28,8 @@
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.FilesetTraversalParams.PackageBoundaryMode;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.analysis.BlazeDirectories;
 import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
 import com.google.devtools.build.lib.analysis.ServerDirectories;
@@ -150,12 +150,13 @@
   }
 
   private Artifact sourceArtifact(String path) {
-    return new Artifact(PathFragment.create(path), Root.asSourceRoot(rootDirectory));
+    return new Artifact(PathFragment.create(path), ArtifactRoot.asSourceRoot(rootDirectory));
   }
 
   private Artifact sourceArtifactUnderPackagePath(String path, String packagePath) {
     return new Artifact(
-        PathFragment.create(path), Root.asSourceRoot(rootDirectory.getRelative(packagePath)));
+        PathFragment.create(path),
+        ArtifactRoot.asSourceRoot(rootDirectory.getRelative(packagePath)));
   }
 
   private Artifact derivedArtifact(String path) {
@@ -164,7 +165,7 @@
     Artifact output =
         new Artifact(
             fullPath,
-            Root.asDerivedRoot(rootDirectory, rootDirectory.getRelative("out")),
+            ArtifactRoot.asDerivedRoot(rootDirectory, rootDirectory.getRelative("out")),
             execPath);
     return output;
   }
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 8e569fc..e5a2ade 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
@@ -40,11 +40,11 @@
 import com.google.devtools.build.lib.actions.ActionLookupValue;
 import com.google.devtools.build.lib.actions.ActionResult;
 import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.BuildFailedException;
 import com.google.devtools.build.lib.actions.Executor;
 import com.google.devtools.build.lib.actions.ResourceManager;
 import com.google.devtools.build.lib.actions.ResourceSet;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.actions.TestExecException;
 import com.google.devtools.build.lib.actions.cache.ActionCache;
 import com.google.devtools.build.lib.actions.cache.Protos.ActionCacheStatistics;
@@ -327,7 +327,7 @@
 
   Artifact createSourceArtifact(FileSystem fs, String name) {
     Path root = fs.getPath(TestUtils.tmpDir());
-    return new Artifact(PathFragment.create(name), Root.asSourceRoot(root));
+    return new Artifact(PathFragment.create(name), ArtifactRoot.asSourceRoot(root));
   }
 
   protected Artifact createDerivedArtifact(String name) {
@@ -340,7 +340,7 @@
     Path path = execRoot.getRelative(execPath);
     return new Artifact(
         path,
-        Root.asDerivedRoot(execRoot, execRoot.getRelative("out")),
+        ArtifactRoot.asDerivedRoot(execRoot, execRoot.getRelative("out")),
         execPath,
         ACTION_LOOKUP_KEY);
   }
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 3846003..1a9063b 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
@@ -40,8 +40,8 @@
 import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
 import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType;
 import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.BuildFailedException;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.actions.cache.MetadataHandler;
 import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
 import com.google.devtools.build.lib.actions.util.TestAction;
@@ -1183,7 +1183,7 @@
     Path path = execRoot.getRelative(execPath);
     return new SpecialArtifact(
         path,
-        Root.asDerivedRoot(execRoot, execRoot.getRelative("out")),
+        ArtifactRoot.asDerivedRoot(execRoot, execRoot.getRelative("out")),
         execPath,
         ACTION_LOOKUP_KEY,
         SpecialArtifactType.TREE);
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 0f346d6..3c32a9d 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
@@ -32,8 +32,8 @@
 import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
 import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType;
 import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.MissingInputFileException;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.actions.cache.DigestUtils;
 import com.google.devtools.build.lib.actions.cache.Metadata;
 import com.google.devtools.build.lib.actions.util.TestAction.DummyAction;
@@ -207,7 +207,10 @@
     Path fullPath = root.getRelative(execPath);
     Artifact output =
         new SpecialArtifact(
-            fullPath, Root.asDerivedRoot(root, root.getRelative("out")), execPath, ALL_OWNER,
+            fullPath,
+            ArtifactRoot.asDerivedRoot(root, root.getRelative("out")),
+            execPath,
+            ALL_OWNER,
             SpecialArtifactType.TREE);
     actions.add(new DummyAction(ImmutableList.<Artifact>of(), output));
     FileSystemUtils.createDirectoryAndParents(fullPath);