Refactor all ctor callsites of PathFragment to instead call a static 'create' method.

This paves the way for changing PathFragment to e.g. an abstract class with multiple subclasses. This way we can split out the windows-specific stuff into one of these concrete classes, making the code more readable and also saving memory (since the shallow heap size of the NonWindowsPathFragment subclass will hopefully be smaller than that of the current PathFragment).

This also lets us pursue gc churn optimizations. We can now do interning in PathFragment#create and can also get rid of unnecessary intermediate PathFragment allocations.

RELNOTES: None

PiperOrigin-RevId: 152145768
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 c0bec56..40c0f94 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
@@ -83,15 +83,15 @@
     alienRoot = Root.asSourceRoot(scratch.dir("/client/workspace"));
     outRoot = Root.asDerivedRoot(execRoot, execRoot.getRelative("out-root/x/bin"));
 
-    fooPath = new PathFragment("foo");
+    fooPath = PathFragment.create("foo");
     fooPackage = PackageIdentifier.createInMainRepo(fooPath);
     fooRelative = fooPath.getRelative("foosource.txt");
 
-    barPath = new PathFragment("foo/bar");
+    barPath = PathFragment.create("foo/bar");
     barPackage = PackageIdentifier.createInMainRepo(barPath);
     barRelative = barPath.getRelative("barsource.txt");
 
-    alienPath = new PathFragment("external/alien");
+    alienPath = PathFragment.create("external/alien");
     alienPackage = PackageIdentifier.create("@alien", alienPath);
     alienRelative = alienPath.getRelative("alien.txt");
 
@@ -116,7 +116,7 @@
   @Test
   public void testGetSourceArtifactUnnormalized() throws Exception {
     assertSame(artifactFactory.getSourceArtifact(fooRelative, clientRoot),
-               artifactFactory.getSourceArtifact(new PathFragment("foo/./foosource.txt"),
+               artifactFactory.getSourceArtifact(PathFragment.create("foo/./foosource.txt"),
                    clientRoot));
   }
 
@@ -156,11 +156,11 @@
     // 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(new PathFragment("")), clientRoot);
+        PackageIdentifier.createInMainRepo(PathFragment.create("")), clientRoot);
     artifactFactory.setPackageRoots(packageRoots);
-    PathFragment outsideWorkspace = new PathFragment("../foo");
+    PathFragment outsideWorkspace = PathFragment.create("../foo");
     PathFragment insideWorkspace =
-        new PathFragment("../" + clientRoot.getPath().getBaseName() + "/foo");
+        PathFragment.create("../" + clientRoot.getPath().getBaseName() + "/foo");
     assertNull(artifactFactory.resolveSourceArtifact(outsideWorkspace, MAIN));
     assertNull("Up-level-containing paths that descend into the right workspace aren't allowed",
             artifactFactory.resolveSourceArtifact(insideWorkspace, MAIN));
@@ -186,7 +186,7 @@
   public void testFindDerivedRoot() throws Exception {
     assertThat(artifactFactory.isDerivedArtifact(fooRelative)).isFalse();
     assertThat(artifactFactory.isDerivedArtifact(
-        new PathFragment("bazel-out/local-fastbuild/bin/foo"))).isTrue();
+        PathFragment.create("bazel-out/local-fastbuild/bin/foo"))).isTrue();
   }
 
   @Test
@@ -210,7 +210,7 @@
 
   @Test
   public void testGetDerivedArtifact() throws Exception {
-    PathFragment toolPath = new PathFragment("_bin/tool");
+    PathFragment toolPath = PathFragment.create("_bin/tool");
     Artifact artifact = artifactFactory.getDerivedArtifact(toolPath, execRoot);
     assertEquals(toolPath, artifact.getExecPath());
     assertEquals(Root.asDerivedRoot(execRoot), artifact.getRoot());
@@ -221,7 +221,7 @@
   @Test
   public void testGetDerivedArtifactFailsForAbsolutePath() throws Exception {
     try {
-      artifactFactory.getDerivedArtifact(new PathFragment("/_bin/b"), execRoot);
+      artifactFactory.getDerivedArtifact(PathFragment.create("/_bin/b"), execRoot);
       fail();
     } catch (IllegalArgumentException e) {
       // Expected exception
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 81b64b2..b7bb9d1 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
@@ -66,8 +66,8 @@
 
   @Test
   public void testEquivalenceRelation() throws Exception {
-    PathFragment aPath = new PathFragment("src/a");
-    PathFragment bPath = new PathFragment("src/b");
+    PathFragment aPath = PathFragment.create("src/a");
+    PathFragment bPath = PathFragment.create("src/b");
     assertEquals(new Artifact(aPath, rootDir),
                  new Artifact(aPath, rootDir));
     assertEquals(new Artifact(bPath, rootDir),
@@ -78,14 +78,14 @@
 
   @Test
   public void testEmptyLabelIsNone() throws Exception {
-    Artifact artifact = new Artifact(new PathFragment("src/a"), rootDir);
+    Artifact artifact = new Artifact(PathFragment.create("src/a"), rootDir);
     assertThat(artifact.getOwnerLabel()).isNull();
   }
 
   @Test
   public void testComparison() throws Exception {
-    PathFragment aPath = new PathFragment("src/a");
-    PathFragment bPath = new PathFragment("src/b");
+    PathFragment aPath = PathFragment.create("src/a");
+    PathFragment bPath = PathFragment.create("src/b");
     Artifact aArtifact = new Artifact(aPath, rootDir);
     Artifact bArtifact = new Artifact(bPath, rootDir);
     assertEquals(-1, Artifact.EXEC_PATH_COMPARATOR.compare(aArtifact, bArtifact));
@@ -165,7 +165,7 @@
     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(new PathFragment("middleman"),
+    Artifact middleman = new Artifact(PathFragment.create("middleman"),
         Root.middlemanRoot(scratch.dir("/foo"), scratch.dir("/foo/out")));
     actionGraph.registerAction(new MiddlemanAction(ActionsTestUtil.NULL_ACTION_OWNER,
         ImmutableList.of(aHeader1, aHeader2, aHeader3), middleman, "desc",
@@ -198,10 +198,10 @@
     Artifact.addExpandedExecPaths(getFooBarArtifacts(actionGraph, true), paths,
         ActionInputHelper.actionGraphArtifactExpander(actionGraph));
     assertThat(paths).containsExactly(
-        new PathFragment("bar1.h"),
-        new PathFragment("bar1.h"),
-        new PathFragment("bar2.h"),
-        new PathFragment("bar3.h"));
+        PathFragment.create("bar1.h"),
+        PathFragment.create("bar1.h"),
+        PathFragment.create("bar2.h"),
+        PathFragment.create("bar3.h"));
   }
 
   @Test
@@ -248,10 +248,10 @@
     Artifact.addExpandedExecPaths(getFooBarArtifacts(actionGraph, true), paths,
         ActionInputHelper.actionGraphArtifactExpander(actionGraph));
     assertThat(paths).containsExactly(
-        new PathFragment("bar1.h"),
-        new PathFragment("bar1.h"),
-        new PathFragment("bar2.h"),
-        new PathFragment("bar3.h"));
+        PathFragment.create("bar1.h"),
+        PathFragment.create("bar1.h"),
+        PathFragment.create("bar2.h"),
+        PathFragment.create("bar3.h"));
   }
 
   // TODO consider tests for the future
@@ -285,7 +285,7 @@
   @Test
   public void testToDetailString() throws Exception {
     Artifact a = new Artifact(scratch.file("/a/b/c"), Root.asDerivedRoot(scratch.dir("/a/b")),
-        new PathFragment("b/c"));
+        PathFragment.create("b/c"));
     assertEquals("[[/a]b]c", a.toDetailString());
   }
 
@@ -293,7 +293,7 @@
   public void testWeirdArtifact() throws Exception {
     try {
       new Artifact(scratch.file("/a/b/c"), Root.asDerivedRoot(scratch.dir("/a")),
-          new PathFragment("c"));
+          PathFragment.create("c"));
       fail();
     } catch (IllegalArgumentException e) {
       assertThat(e).hasMessage(
@@ -312,7 +312,7 @@
   public void testSerializeToStringWithExecPath() throws Exception {
     Path path = scratch.file("/aaa/bbb/ccc");
     Root root = Root.asDerivedRoot(scratch.dir("/aaa/bbb"));
-    PathFragment execPath = new PathFragment("bbb/ccc");
+    PathFragment execPath = PathFragment.create("bbb/ccc");
 
     assertEquals("bbb/ccc /3", new Artifact(path, root, execPath).serializeToString());
   }
@@ -321,7 +321,7 @@
   public void testSerializeToStringWithOwner() throws Exception {
     assertEquals("b/c /3 //foo:bar",
         new Artifact(scratch.file("/aa/b/c"), Root.asDerivedRoot(scratch.dir("/aa")),
-            new PathFragment("b/c"),
+            PathFragment.create("b/c"),
             new LabelArtifactOwner(Label.parseAbsoluteUnchecked("//foo:bar"))).serializeToString());
   }
 
@@ -353,7 +353,7 @@
   public void testIsSourceArtifact() throws Exception {
     assertThat(
         new Artifact(scratch.file("/src/foo.cc"), Root.asSourceRoot(scratch.dir("/")),
-            new PathFragment("src/foo.cc"))
+            PathFragment.create("src/foo.cc"))
             .isSourceArtifact())
         .isTrue();
     assertThat(
diff --git a/src/test/java/com/google/devtools/build/lib/actions/BaseSpawnTest.java b/src/test/java/com/google/devtools/build/lib/actions/BaseSpawnTest.java
index 7f339dc..0c1b0f5 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/BaseSpawnTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/BaseSpawnTest.java
@@ -44,7 +44,7 @@
     final String runfilesDir = "runfilesdir";
     BaseSpawn underTest = minimalBaseSpawn(
         baseEnviron,
-        new RunfilesSupplierImpl(new PathFragment(runfilesDir), Runfiles.EMPTY));
+        new RunfilesSupplierImpl(PathFragment.create(runfilesDir), Runfiles.EMPTY));
 
     Map<String, String> expected = ImmutableMap.<String, String>builder()
         .putAll(baseEnviron)
@@ -60,8 +60,8 @@
     Map<String, String> baseEnviron = ImmutableMap.of("HELLO", "world");
     BaseSpawn underTest = minimalBaseSpawn(baseEnviron,
         new CompositeRunfilesSupplier(
-            new RunfilesSupplierImpl(new PathFragment("rfdir1"), Runfiles.EMPTY),
-            new RunfilesSupplierImpl(new PathFragment("rfdir2"), Runfiles.EMPTY)));
+            new RunfilesSupplierImpl(PathFragment.create("rfdir1"), Runfiles.EMPTY),
+            new RunfilesSupplierImpl(PathFragment.create("rfdir2"), Runfiles.EMPTY)));
 
     assertThat(underTest.getEnvironment()).isEqualTo(baseEnviron);
   }
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 507fc8b..559deb1 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
@@ -61,9 +61,9 @@
 
   @Test
   public void testGetRunfilesDirsReturnsCombinedPaths() {
-    PathFragment first = new PathFragment("first");
-    PathFragment second = new PathFragment("second");
-    PathFragment shared = new PathFragment("shared");
+    PathFragment first = PathFragment.create("first");
+    PathFragment second = PathFragment.create("second");
+    PathFragment shared = PathFragment.create("shared");
 
     when(mockFirst.getRunfilesDirs()).thenReturn(ImmutableSet.of(first, shared));
     when(mockSecond.getRunfilesDirs()).thenReturn(ImmutableSet.of(second, shared));
@@ -75,13 +75,13 @@
 
   @Test
   public void testGetMappingsReturnsMappingsWithFirstPrecedenceOverSecond() throws IOException {
-    PathFragment first = new PathFragment("first");
+    PathFragment first = PathFragment.create("first");
     Map<PathFragment, Artifact> firstMappings = mkMappings(rootDir, "first1", "first2");
 
-    PathFragment second = new PathFragment("second");
+    PathFragment second = PathFragment.create("second");
     Map<PathFragment, Artifact> secondMappings = mkMappings(rootDir, "second1", "second2");
 
-    PathFragment shared = new PathFragment("shared");
+    PathFragment shared = PathFragment.create("shared");
     Map<PathFragment, Artifact> firstSharedMappings = mkMappings(rootDir, "shared1", "shared2");
     Map<PathFragment, Artifact> secondSharedMappings = mkMappings(rootDir, "lost1", "lost2");
 
@@ -103,13 +103,13 @@
   @Test
   public void testGetMappingsViaListConstructorReturnsMappingsWithFirstPrecedenceOverSecond()
       throws IOException {
-    PathFragment first = new PathFragment("first");
+    PathFragment first = PathFragment.create("first");
     Map<PathFragment, Artifact> firstMappings = mkMappings(rootDir, "first1", "first2");
 
-    PathFragment second = new PathFragment("second");
+    PathFragment second = PathFragment.create("second");
     Map<PathFragment, Artifact> secondMappings = mkMappings(rootDir, "second1", "second2");
 
-    PathFragment shared = new PathFragment("shared");
+    PathFragment shared = PathFragment.create("shared");
     Map<PathFragment, Artifact> firstSharedMappings = mkMappings(rootDir, "shared1", "shared2");
     Map<PathFragment, Artifact> secondSharedMappings = mkMappings(rootDir, "lost1", "lost2");
 
@@ -132,13 +132,13 @@
   private static Map<PathFragment, Artifact> mkMappings(Root rootDir, String... paths) {
     ImmutableMap.Builder<PathFragment, Artifact> builder = ImmutableMap.builder();
     for (String path : paths) {
-      builder.put(new PathFragment(path), mkArtifact(rootDir, path));
+      builder.put(PathFragment.create(path), mkArtifact(rootDir, path));
     }
     return builder.build();
   }
 
   private static Artifact mkArtifact(Root rootDir, String path) {
-    return new Artifact(new PathFragment(path), rootDir);
+    return new Artifact(PathFragment.create(path), rootDir);
   }
 
   private static List<Artifact> mkArtifacts(Root rootDir, String... paths) {
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 21b4b30..c0a808e 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
@@ -273,7 +273,7 @@
   }
 
   private Artifact createTreeArtifact(String rootRelativePath) {
-    PathFragment relpath = new PathFragment(rootRelativePath);
+    PathFragment relpath = PathFragment.create(rootRelativePath);
     return new SpecialArtifact(
         rootDir.getPath().getRelative(relpath),
         rootDir,
@@ -286,6 +286,6 @@
       Artifact inputTreeArtifact, String parentRelativePath) {
     return ActionInputHelper.treeFileArtifact(
         inputTreeArtifact,
-        new PathFragment(parentRelativePath));
+        PathFragment.create(parentRelativePath));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/actions/RootTest.java b/src/test/java/com/google/devtools/build/lib/actions/RootTest.java
index 26f0ef0..92b0567 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/RootTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/RootTest.java
@@ -62,7 +62,7 @@
     Path rootDir = scratch.dir("/exec/root");
     Root root = Root.asDerivedRoot(execRoot, rootDir);
     assertFalse(root.isSourceRoot());
-    assertEquals(new PathFragment("root"), root.getExecPath());
+    assertEquals(PathFragment.create("root"), root.getExecPath());
     assertEquals(rootDir, root.getPath());
     assertEquals("/exec/root[derived]", root.toString());
   }
diff --git a/src/test/java/com/google/devtools/build/lib/actions/cache/CompactPersistentActionCacheTest.java b/src/test/java/com/google/devtools/build/lib/actions/cache/CompactPersistentActionCacheTest.java
index 479e152..b731f6f 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/cache/CompactPersistentActionCacheTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/cache/CompactPersistentActionCacheTest.java
@@ -167,7 +167,7 @@
     ActionCache.Entry entry =
         new ActionCache.Entry("actionKey", ImmutableMap.<String, String>of(), false);
     entry.toString();
-    entry.addFile(new PathFragment("foo/bar"), Metadata.CONSTANT_METADATA);
+    entry.addFile(PathFragment.create("foo/bar"), Metadata.CONSTANT_METADATA);
     entry.toString();
     entry.getFileDigest();
     entry.toString();
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 24d321c..cbf98e1 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
@@ -192,7 +192,7 @@
   }
 
   public static final Artifact DUMMY_ARTIFACT = new Artifact(
-      new PathFragment("dummy"),
+      PathFragment.create("dummy"),
       Root.asSourceRoot(new InMemoryFileSystem().getRootDirectory()));
 
   public static final ActionOwner NULL_ACTION_OWNER =
@@ -549,7 +549,7 @@
       Artifact inputTreeArtifact, Artifact outputTreeArtifact) {
     return new SpawnActionTemplate.Builder(inputTreeArtifact, outputTreeArtifact)
         .setCommandLineTemplate(CustomCommandLine.builder().build())
-        .setExecutable(new PathFragment("bin/executable"))
+        .setExecutable(PathFragment.create("bin/executable"))
         .setOutputPathMapper(new OutputPathMapper() {
           @Override
           public PathFragment parentRelativeOutputPath(TreeFileArtifact inputTreeFileArtifact) {
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/BuildViewTest.java b/src/test/java/com/google/devtools/build/lib/analysis/BuildViewTest.java
index 3bf92ec..106ccd1 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/BuildViewTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/BuildViewTest.java
@@ -162,7 +162,7 @@
         outputArtifact.getRoot());
     assertEquals(outputCT.getConfiguration().getBinFragment().getRelative("pkg/a.out"),
         outputArtifact.getExecPath());
-    assertEquals(new PathFragment("pkg/a.out"), outputArtifact.getRootRelativePath());
+    assertEquals(PathFragment.create("pkg/a.out"), outputArtifact.getRootRelativePath());
 
     Action action = getGeneratingAction(outputArtifact);
     assertSame(FailAction.class, action.getClass());
@@ -775,9 +775,9 @@
     Path cycles2BuildFilePath = scratch.file("cycles2/BUILD",
         "sh_library(name = 'cycles2', srcs = glob(['*.sh']))");
     cycles1BuildFilePath.getParentDirectory().getRelative("cycles1.sh").createSymbolicLink(
-        new PathFragment("cycles1.sh"));
+        PathFragment.create("cycles1.sh"));
     cycles2BuildFilePath.getParentDirectory().getRelative("cycles2.sh").createSymbolicLink(
-        new PathFragment("cycles2.sh"));
+        PathFragment.create("cycles2.sh"));
     reporter.removeHandler(failFastHandler);
     EventBus eventBus = new EventBus();
     LoadingFailureRecorder recorder = new LoadingFailureRecorder();
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 0234699..e54ddc3 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
@@ -52,7 +52,7 @@
     List<Artifact> artifacts = mkArtifacts(rootDir, "thing1", "thing2");
 
     RunfilesSupplierImpl underTest =
-        new RunfilesSupplierImpl(new PathFragment("notimportant"), mkRunfiles(artifacts));
+        new RunfilesSupplierImpl(PathFragment.create("notimportant"), mkRunfiles(artifacts));
 
     assertThat(underTest.getArtifacts()).containsExactlyElementsIn(artifacts);
   }
@@ -60,11 +60,11 @@
   @Test
   public void testGetArtifactsFilterMiddlemen() {
     List<Artifact> artifacts = mkArtifacts(rootDir, "thing1", "thing2");
-    Artifact middleman = new Artifact(new PathFragment("middleman"), middlemanRoot);
+    Artifact middleman = new Artifact(PathFragment.create("middleman"), middlemanRoot);
     Runfiles runfiles = mkRunfiles(Iterables.concat(artifacts, ImmutableList.of(middleman)));
 
     RunfilesSupplier underTest =
-        new RunfilesSupplierImpl(new PathFragment("notimportant"), runfiles);
+        new RunfilesSupplierImpl(PathFragment.create("notimportant"), runfiles);
 
     assertThat(underTest.getArtifacts()).containsExactlyElementsIn(artifacts);
   }
@@ -72,15 +72,15 @@
   @Test
   public void testGetManifestsWhenNone() {
     RunfilesSupplier underTest =
-        new RunfilesSupplierImpl(new PathFragment("ignored"), Runfiles.EMPTY, null);
+        new RunfilesSupplierImpl(PathFragment.create("ignored"), Runfiles.EMPTY, null);
     assertThat(underTest.getManifests()).isEmpty();
   }
 
   @Test
   public void testGetManifestsWhenSupplied() {
-    Artifact manifest = new Artifact(new PathFragment("manifest"), rootDir);
+    Artifact manifest = new Artifact(PathFragment.create("manifest"), rootDir);
     RunfilesSupplier underTest =
-        new RunfilesSupplierImpl(new PathFragment("ignored"), Runfiles.EMPTY, manifest);
+        new RunfilesSupplierImpl(PathFragment.create("ignored"), Runfiles.EMPTY, manifest);
     assertThat(underTest.getManifests()).containsExactly(manifest);
   }
 
@@ -91,7 +91,7 @@
   private static List<Artifact> mkArtifacts(Root rootDir, String... paths) {
     ImmutableList.Builder<Artifact> builder = ImmutableList.builder();
     for (String path : paths) {
-      builder.add(new Artifact(new PathFragment(path), rootDir));
+      builder.add(new Artifact(PathFragment.create(path), rootDir));
     }
     return builder.build();
   }
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 f6d1509..41f5436 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
@@ -50,11 +50,11 @@
   @Test
   public void testFilterListForObscuringSymlinksCatchesBadObscurer() throws Exception {
     Map<PathFragment, Artifact> obscuringMap = new HashMap<>();
-    PathFragment pathA = new PathFragment("a");
+    PathFragment pathA = PathFragment.create("a");
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    Artifact artifactA = new Artifact(new PathFragment("a"), root);
+    Artifact artifactA = new Artifact(PathFragment.create("a"), root);
     obscuringMap.put(pathA, artifactA);
-    obscuringMap.put(new PathFragment("a/b"), new Artifact(new PathFragment("c/b"),
+    obscuringMap.put(PathFragment.create("a/b"), new Artifact(PathFragment.create("c/b"),
         root));
     assertThat(Runfiles.filterListForObscuringSymlinks(reporter, null, obscuringMap).entrySet())
         .containsExactly(Maps.immutableEntry(pathA, artifactA)).inOrder();
@@ -64,12 +64,12 @@
   @Test
   public void testFilterListForObscuringSymlinksCatchesBadGrandParentObscurer() throws Exception {
     Map<PathFragment, Artifact> obscuringMap = new HashMap<>();
-    PathFragment pathA = new PathFragment("a");
+    PathFragment pathA = PathFragment.create("a");
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    Artifact artifactA = new Artifact(new PathFragment("a"),
+    Artifact artifactA = new Artifact(PathFragment.create("a"),
                                           root);
     obscuringMap.put(pathA, artifactA);
-    obscuringMap.put(new PathFragment("a/b/c"), new Artifact(new PathFragment("b/c"),
+    obscuringMap.put(PathFragment.create("a/b/c"), new Artifact(PathFragment.create("b/c"),
                                                          root));
     assertThat(Runfiles.filterListForObscuringSymlinks(reporter, null, obscuringMap).entrySet())
         .containsExactly(Maps.immutableEntry(pathA, artifactA)).inOrder();
@@ -79,12 +79,12 @@
   @Test
   public void testFilterListForObscuringSymlinksCatchesBadObscurerNoListener() throws Exception {
     Map<PathFragment, Artifact> obscuringMap = new HashMap<>();
-    PathFragment pathA = new PathFragment("a");
+    PathFragment pathA = PathFragment.create("a");
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    Artifact artifactA = new Artifact(new PathFragment("a"),
+    Artifact artifactA = new Artifact(PathFragment.create("a"),
                                           root);
     obscuringMap.put(pathA, artifactA);
-    obscuringMap.put(new PathFragment("a/b"), new Artifact(new PathFragment("c/b"),
+    obscuringMap.put(PathFragment.create("a/b"), new Artifact(PathFragment.create("c/b"),
         root));
     assertThat(Runfiles.filterListForObscuringSymlinks(null, null, obscuringMap).entrySet())
         .containsExactly(Maps.immutableEntry(pathA, artifactA)).inOrder();
@@ -93,12 +93,12 @@
   @Test
   public void testFilterListForObscuringSymlinksIgnoresOkObscurer() throws Exception {
     Map<PathFragment, Artifact> obscuringMap = new HashMap<>();
-    PathFragment pathA = new PathFragment("a");
+    PathFragment pathA = PathFragment.create("a");
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    Artifact artifactA = new Artifact(new PathFragment("a"),
+    Artifact artifactA = new Artifact(PathFragment.create("a"),
                                           root);
     obscuringMap.put(pathA, artifactA);
-    obscuringMap.put(new PathFragment("a/b"), new Artifact(new PathFragment("a/b"),
+    obscuringMap.put(PathFragment.create("a/b"), new Artifact(PathFragment.create("a/b"),
                                                          root));
 
     assertThat(Runfiles.filterListForObscuringSymlinks(reporter, null, obscuringMap).entrySet())
@@ -109,13 +109,13 @@
   @Test
   public void testFilterListForObscuringSymlinksNoObscurers() throws Exception {
     Map<PathFragment, Artifact> obscuringMap = new HashMap<>();
-    PathFragment pathA = new PathFragment("a");
+    PathFragment pathA = PathFragment.create("a");
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    Artifact artifactA = new Artifact(new PathFragment("a"),
+    Artifact artifactA = new Artifact(PathFragment.create("a"),
                                           root);
     obscuringMap.put(pathA, artifactA);
-    PathFragment pathBC = new PathFragment("b/c");
-    Artifact artifactBC = new Artifact(new PathFragment("a/b"),
+    PathFragment pathBC = PathFragment.create("b/c");
+    Artifact artifactBC = new Artifact(PathFragment.create("a/b"),
                                        root);
     obscuringMap.put(pathBC, artifactBC);
     assertThat(Runfiles.filterListForObscuringSymlinks(reporter, null, obscuringMap)
@@ -139,9 +139,9 @@
   @Test
   public void testPutCatchesConflict() {
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    PathFragment pathA = new PathFragment("a");
-    Artifact artifactB = new Artifact(new PathFragment("b"), root);
-    Artifact artifactC = new Artifact(new PathFragment("c"), root);
+    PathFragment pathA = PathFragment.create("a");
+    Artifact artifactB = new Artifact(PathFragment.create("b"), root);
+    Artifact artifactC = new Artifact(PathFragment.create("c"), root);
     Map<PathFragment, Artifact> map = new LinkedHashMap<>();
 
     Runfiles.ConflictChecker checker =
@@ -156,9 +156,9 @@
   @Test
   public void testPutReportsError() {
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    PathFragment pathA = new PathFragment("a");
-    Artifact artifactB = new Artifact(new PathFragment("b"), root);
-    Artifact artifactC = new Artifact(new PathFragment("c"), root);
+    PathFragment pathA = PathFragment.create("a");
+    Artifact artifactB = new Artifact(PathFragment.create("b"), root);
+    Artifact artifactC = new Artifact(PathFragment.create("c"), root);
     Map<PathFragment, Artifact> map = new LinkedHashMap<>();
 
     // Same as above but with ERROR not WARNING
@@ -174,8 +174,8 @@
   @Test
   public void testPutCatchesConflictBetweenNullAndNotNull() {
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    PathFragment pathA = new PathFragment("a");
-    Artifact artifactB = new Artifact(new PathFragment("b"), root);
+    PathFragment pathA = PathFragment.create("a");
+    Artifact artifactB = new Artifact(PathFragment.create("b"), root);
     Map<PathFragment, Artifact> map = new LinkedHashMap<>();
 
     Runfiles.ConflictChecker checker =
@@ -189,8 +189,8 @@
   @Test
   public void testPutCatchesConflictBetweenNotNullAndNull() {
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    PathFragment pathA = new PathFragment("a");
-    Artifact artifactB = new Artifact(new PathFragment("b"), root);
+    PathFragment pathA = PathFragment.create("a");
+    Artifact artifactB = new Artifact(PathFragment.create("b"), root);
     Map<PathFragment, Artifact> map = new LinkedHashMap<>();
 
     // Same as above but opposite order
@@ -205,9 +205,9 @@
   @Test
   public void testPutIgnoresConflict() {
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    PathFragment pathA = new PathFragment("a");
-    Artifact artifactB = new Artifact(new PathFragment("b"), root);
-    Artifact artifactC = new Artifact(new PathFragment("c"), root);
+    PathFragment pathA = PathFragment.create("a");
+    Artifact artifactB = new Artifact(PathFragment.create("b"), root);
+    Artifact artifactC = new Artifact(PathFragment.create("c"), root);
     Map<PathFragment, Artifact> map = new LinkedHashMap<>();
 
     Runfiles.ConflictChecker checker =
@@ -221,9 +221,9 @@
   @Test
   public void testPutIgnoresConflictNoListener() {
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    PathFragment pathA = new PathFragment("a");
-    Artifact artifactB = new Artifact(new PathFragment("b"), root);
-    Artifact artifactC = new Artifact(new PathFragment("c"), root);
+    PathFragment pathA = PathFragment.create("a");
+    Artifact artifactB = new Artifact(PathFragment.create("b"), root);
+    Artifact artifactC = new Artifact(PathFragment.create("c"), root);
     Map<PathFragment, Artifact> map = new LinkedHashMap<>();
 
     Runfiles.ConflictChecker checker =
@@ -237,9 +237,9 @@
   @Test
   public void testPutIgnoresSameArtifact() {
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    PathFragment pathA = new PathFragment("a");
-    Artifact artifactB = new Artifact(new PathFragment("b"), root);
-    Artifact artifactB2 = new Artifact(new PathFragment("b"), root);
+    PathFragment pathA = PathFragment.create("a");
+    Artifact artifactB = new Artifact(PathFragment.create("b"), root);
+    Artifact artifactB2 = new Artifact(PathFragment.create("b"), root);
     assertEquals(artifactB, artifactB2);
     Map<PathFragment, Artifact> map = new LinkedHashMap<>();
 
@@ -253,7 +253,7 @@
 
   @Test
   public void testPutIgnoresNullAndNull() {
-    PathFragment pathA = new PathFragment("a");
+    PathFragment pathA = PathFragment.create("a");
     Map<PathFragment, Artifact> map = new LinkedHashMap<>();
 
     Runfiles.ConflictChecker checker =
@@ -268,11 +268,11 @@
   @Test
   public void testPutNoConflicts() {
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    PathFragment pathA = new PathFragment("a");
-    PathFragment pathB = new PathFragment("b");
-    PathFragment pathC = new PathFragment("c");
-    Artifact artifactA = new Artifact(new PathFragment("a"), root);
-    Artifact artifactB = new Artifact(new PathFragment("b"), root);
+    PathFragment pathA = PathFragment.create("a");
+    PathFragment pathB = PathFragment.create("b");
+    PathFragment pathC = PathFragment.create("c");
+    Artifact artifactA = new Artifact(PathFragment.create("a"), root);
+    Artifact artifactB = new Artifact(PathFragment.create("b"), root);
     Map<PathFragment, Artifact> map = new LinkedHashMap<>();
 
     Runfiles.ConflictChecker checker =
@@ -322,8 +322,8 @@
   @Test
   public void testLegacyRunfilesStructure() {
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    PathFragment workspaceName = new PathFragment("wsname");
-    PathFragment pathB = new PathFragment("external/repo/b");
+    PathFragment workspaceName = PathFragment.create("wsname");
+    PathFragment pathB = PathFragment.create("external/repo/b");
     Artifact artifactB = new Artifact(pathB, root);
 
     Runfiles.ManifestBuilder builder = new Runfiles.ManifestBuilder(workspaceName, true);
@@ -336,15 +336,15 @@
 
     assertThat(builder.build().entrySet()).containsExactly(
         Maps.immutableEntry(workspaceName.getRelative(pathB), artifactB),
-        Maps.immutableEntry(new PathFragment("repo/b"), artifactB));
+        Maps.immutableEntry(PathFragment.create("repo/b"), artifactB));
     assertNoEvents();
   }
 
   @Test
   public void testRunfileAdded() {
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    PathFragment workspaceName = new PathFragment("wsname");
-    PathFragment pathB = new PathFragment("external/repo/b");
+    PathFragment workspaceName = PathFragment.create("wsname");
+    PathFragment pathB = PathFragment.create("external/repo/b");
     Artifact artifactB = new Artifact(pathB, root);
 
     Runfiles.ManifestBuilder builder = new Runfiles.ManifestBuilder(workspaceName, false);
@@ -358,7 +358,7 @@
 
     assertThat(builder.build().entrySet()).containsExactly(
         Maps.immutableEntry(workspaceName.getRelative(".runfile"), null),
-        Maps.immutableEntry(new PathFragment("repo/b"), artifactB));
+        Maps.immutableEntry(PathFragment.create("repo/b"), artifactB));
     assertNoEvents();
   }
 
@@ -366,7 +366,7 @@
   @Test
   public void testConflictWithExternal() {
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    PathFragment pathB = new PathFragment("repo/b");
+    PathFragment pathB = PathFragment.create("repo/b");
     PathFragment externalPathB = Label.EXTERNAL_PACKAGE_NAME.getRelative(pathB);
     Artifact artifactB = new Artifact(pathB, root);
     Artifact artifactExternalB = new Artifact(externalPathB, root);
@@ -383,17 +383,17 @@
     builder.addUnderWorkspace(inputManifest, checker);
 
     assertThat(builder.build().entrySet()).containsExactly(
-        Maps.immutableEntry(new PathFragment("repo/b"), artifactExternalB));
+        Maps.immutableEntry(PathFragment.create("repo/b"), artifactExternalB));
     checkConflictWarning();
   }
 
   @Test
   public void testMergeWithSymlinks() {
     Root root = Root.asSourceRoot(scratch.resolve("/workspace"));
-    Artifact artifactA = new Artifact(new PathFragment("a/target"), root);
-    Artifact artifactB = new Artifact(new PathFragment("b/target"), root);
-    PathFragment sympathA = new PathFragment("a/symlink");
-    PathFragment sympathB = new PathFragment("b/symlink");
+    Artifact artifactA = new Artifact(PathFragment.create("a/target"), root);
+    Artifact artifactB = new Artifact(PathFragment.create("b/target"), root);
+    PathFragment sympathA = PathFragment.create("a/symlink");
+    PathFragment sympathB = PathFragment.create("b/symlink");
     Runfiles runfilesA = new Runfiles.Builder("TESTING")
         .addSymlink(sympathA, artifactA)
         .build();
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/UtilTest.java b/src/test/java/com/google/devtools/build/lib/analysis/UtilTest.java
index 1bc67df..9024942 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/UtilTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/UtilTest.java
@@ -30,7 +30,7 @@
 
   @Test
   public void testContainsHyphen() throws Exception {
-    assertTrue(Util.containsHyphen(new PathFragment("foo/bar/with-hyphen")));
-    assertFalse(Util.containsHyphen(new PathFragment("foo/bar/no/hyphen")));
+    assertTrue(Util.containsHyphen(PathFragment.create("foo/bar/with-hyphen")));
+    assertFalse(Util.containsHyphen(PathFragment.create("foo/bar/no/hyphen")));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLineTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLineTest.java
index f065df9..fb28f70 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLineTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLineTest.java
@@ -32,7 +32,7 @@
     CustomCommandLine commandLine = new CustomCommandLine.Builder()
         .add("foo")
         .addBeforeEachPath(
-            "-I", ImmutableList.of(new PathFragment("/path1"), new PathFragment("/path2")))
+            "-I", ImmutableList.of(PathFragment.create("/path1"), PathFragment.create("/path2")))
         .add("bar")
         .addBeforeEachPath("-I", ImmutableList.<PathFragment>of())
         .add("baz")
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 d35f103..dbf57ae 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
@@ -102,7 +102,7 @@
   }
 
   private Artifact createTreeArtifact(String rootRelativePath) {
-    PathFragment relpath = new PathFragment(rootRelativePath);
+    PathFragment relpath = PathFragment.create(rootRelativePath);
     return new SpecialArtifact(
         rootDir.getPath().getRelative(relpath),
         rootDir,
@@ -115,7 +115,7 @@
       Artifact inputTreeArtifact, String parentRelativePath) {
     return ActionInputHelper.treeFileArtifact(
         inputTreeArtifact,
-        new PathFragment(parentRelativePath));
+        PathFragment.create(parentRelativePath));
   }
 
   private ParameterFileWriteAction createParameterFileWriteAction(
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 a221496..19261f2 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
@@ -325,7 +325,7 @@
   }
 
   private Artifact createTreeArtifact(String rootRelativePath) {
-    PathFragment relpath = new PathFragment(rootRelativePath);
+    PathFragment relpath = PathFragment.create(rootRelativePath);
     return new SpecialArtifact(
         root.getPath().getRelative(relpath),
         root,
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 5d45da6..09c6b0d 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
@@ -92,7 +92,7 @@
     Artifact outputTreeArtifact = createOutputTreeArtifact();
     SpawnActionTemplate.Builder builder = builder(inputTreeArtifact, outputTreeArtifact)
         .setExecutionInfo(ImmutableMap.<String, String>of("local", ""))
-        .setExecutable(new PathFragment("/bin/cp"))
+        .setExecutable(PathFragment.create("/bin/cp"))
         .setCommandLineTemplate(
             createSimpleCommandLineTemplate(inputTreeArtifact, outputTreeArtifact))
         .setMnemonics("ActionTemplate", "ExpandedAction");
@@ -127,7 +127,7 @@
     SpawnActionTemplate.Builder builder = builder(inputTreeArtifact, outputTreeArtifact)
         .setExecutionInfo(ImmutableMap.<String, String>of("local", ""))
         .setOutputPathMapper(IDENTITY_MAPPER)
-        .setExecutable(new PathFragment("/bin/cp"))
+        .setExecutable(PathFragment.create("/bin/cp"))
         .setMnemonics("ActionTemplate", "ExpandedAction");
 
     try {
@@ -155,10 +155,10 @@
       String baseName = String.format("child%d", i);
       assertThat(expandedActions.get(i).getInputs()).containsExactly(
           ActionInputHelper.treeFileArtifact(
-              inputTreeArtifact, new PathFragment("children/" + baseName)));
+              inputTreeArtifact, PathFragment.create("children/" + baseName)));
       assertThat(expandedActions.get(i).getOutputs()).containsExactly(
           ActionInputHelper.treeFileArtifact(
-              outputTreeArtifact, new PathFragment("children/" + baseName)));
+              outputTreeArtifact, PathFragment.create("children/" + baseName)));
     }
   }
 
@@ -247,14 +247,14 @@
         createInputTreeFileArtifacts(inputTreeArtifact);
 
     SpawnActionTemplate.Builder builder = builder(inputTreeArtifact, outputTreeArtifact)
-        .setExecutable(new PathFragment("/bin/cp"))
+        .setExecutable(PathFragment.create("/bin/cp"))
         .setCommandLineTemplate(
             createSimpleCommandLineTemplate(inputTreeArtifact, outputTreeArtifact));
 
     OutputPathMapper mapper = new OutputPathMapper() {
       @Override
       public PathFragment parentRelativeOutputPath(TreeFileArtifact inputTreeFileArtifact) {
-        return new PathFragment("//absolute/" + inputTreeFileArtifact.getParentRelativePath());
+        return PathFragment.create("//absolute/" + inputTreeFileArtifact.getParentRelativePath());
       }
     };
 
@@ -272,7 +272,7 @@
     mapper = new OutputPathMapper() {
       @Override
       public PathFragment parentRelativeOutputPath(TreeFileArtifact inputTreeFileArtifact) {
-        return new PathFragment("../" + inputTreeFileArtifact.getParentRelativePath());
+        return PathFragment.create("../" + inputTreeFileArtifact.getParentRelativePath());
       }
     };
 
@@ -300,7 +300,7 @@
     return builder(inputTreeArtifact, outputTreeArtifact)
         .setExecutionInfo(ImmutableMap.<String, String>of("local", ""))
         .setEnvironment(ImmutableMap.<String, String>of("env", "value"))
-        .setExecutable(new PathFragment("/bin/cp"))
+        .setExecutable(PathFragment.create("/bin/cp"))
         .setCommandLineTemplate(
             createSimpleCommandLineTemplate(inputTreeArtifact, outputTreeArtifact))
         .setOutputPathMapper(IDENTITY_MAPPER)
@@ -317,7 +317,7 @@
   }
 
   private Artifact createTreeArtifact(String rootRelativePath) {
-    PathFragment relpath = new PathFragment(rootRelativePath);
+    PathFragment relpath = PathFragment.create(rootRelativePath);
     return new SpecialArtifact(
         root.getPath().getRelative(relpath),
         root,
@@ -327,7 +327,7 @@
   }
 
   private Artifact createDerivedArtifact(String rootRelativePath) {
-    return new Artifact(new PathFragment(rootRelativePath), root);
+    return new Artifact(PathFragment.create(rootRelativePath), root);
   }
 
   private CustomCommandLine createSimpleCommandLineTemplate(
@@ -342,8 +342,8 @@
     return ActionInputHelper.asTreeFileArtifacts(
         inputTreeArtifact,
         ImmutableList.of(
-            new PathFragment("children/child0"),
-            new PathFragment("children/child1"),
-            new PathFragment("children/child2")));
+            PathFragment.create("children/child0"),
+            PathFragment.create("children/child1"),
+            PathFragment.create("children/child2")));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTest.java
index 8aef0e6..8629684 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTest.java
@@ -77,7 +77,7 @@
   }
 
   private SpawnAction createCopyFromWelcomeToDestination(Map<String, String> environmentVariables) {
-    PathFragment cp = new PathFragment("/bin/cp");
+    PathFragment cp = PathFragment.create("/bin/cp");
     List<String> arguments = asList(welcomeArtifact.getExecPath().getPathString(),
         destinationArtifact.getExecPath().getPathString());
 
@@ -275,7 +275,7 @@
     Artifact output1 = getBinArtifactWithNoOwner("output1");
     Artifact output2 = getBinArtifactWithNoOwner("output2");
     Artifact paramFile = getBinArtifactWithNoOwner("output1-2.params");
-    PathFragment executable = new PathFragment("/bin/executable");
+    PathFragment executable = PathFragment.create("/bin/executable");
 
     useConfiguration("--min_param_file_size=500");
 
@@ -353,7 +353,7 @@
     Action[] actions = builder()
         .addInput(manifest)
         .addRunfilesSupplier(
-            new RunfilesSupplierImpl(new PathFragment("destination"), Runfiles.EMPTY, manifest))
+            new RunfilesSupplierImpl(PathFragment.create("destination"), Runfiles.EMPTY, manifest))
         .addOutput(getBinArtifactWithNoOwner("output"))
         .setExecutable(scratch.file("/bin/xxx").asFragment())
         .setProgressMessage("Test")
@@ -385,15 +385,15 @@
         builder.setMnemonic((i & 4) == 0 ? "a" : "b");
 
         if ((i & 8) == 0) {
-          builder.addRunfilesSupplier(runfilesSupplier(artifactA, new PathFragment("a")));
+          builder.addRunfilesSupplier(runfilesSupplier(artifactA, PathFragment.create("a")));
         } else {
-          builder.addRunfilesSupplier(runfilesSupplier(artifactB, new PathFragment("a")));
+          builder.addRunfilesSupplier(runfilesSupplier(artifactB, PathFragment.create("a")));
         }
 
         if ((i & 16) == 0) {
-          builder.addRunfilesSupplier(runfilesSupplier(artifactA, new PathFragment("aa")));
+          builder.addRunfilesSupplier(runfilesSupplier(artifactA, PathFragment.create("aa")));
         } else {
-          builder.addRunfilesSupplier(runfilesSupplier(artifactA, new PathFragment("ab")));
+          builder.addRunfilesSupplier(runfilesSupplier(artifactA, PathFragment.create("ab")));
         }
 
         Map<String, String> env = new HashMap<>();
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 f821e46..eb25ec3 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
@@ -277,10 +277,10 @@
         ArtifactFactory artifactFactory, ArtifactOwner artifactOwner, Supplier<UUID> buildId,
         String workspaceName) {
       Artifact stableStatus = artifactFactory.getDerivedArtifact(
-          new PathFragment("build-info.txt"),
+          PathFragment.create("build-info.txt"),
           directories.getBuildDataDirectory(workspaceName), artifactOwner);
       Artifact volatileStatus = artifactFactory.getConstantMetadataArtifact(
-          new PathFragment("build-changelist.txt"),
+          PathFragment.create("build-changelist.txt"),
           directories.getBuildDataDirectory(workspaceName), artifactOwner);
       return new DummyWorkspaceStatusAction(key, stableStatus, volatileStatus);
     }
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestBase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestBase.java
index d8acbcf..184ba7d 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestBase.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestBase.java
@@ -107,7 +107,7 @@
     Path symlinkcycleBuildFile = scratch.file("symlinkcycle/BUILD",
         "sh_library(name = 'cycle', srcs = glob(['*.sh']))");
     Path dirPath = symlinkcycleBuildFile.getParentDirectory();
-    dirPath.getRelative("foo.sh").createSymbolicLink(new PathFragment("foo.sh"));
+    dirPath.getRelative("foo.sh").createSymbolicLink(PathFragment.create("foo.sh"));
     scratch.file("okaypkg/BUILD",
         "sh_library(name = 'transitively-a-cycle',",
         "           srcs = ['//symlinkcycle:cycle'])");
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 576a312..47a59a4 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
@@ -773,7 +773,7 @@
     }
     skyframeExecutor.invalidateFilesUnderPathForTesting(
         reporter,
-        new ModifiedFileSet.Builder().modify(new PathFragment(buildFilePathString)).build(),
+        new ModifiedFileSet.Builder().modify(PathFragment.create(buildFilePathString)).build(),
         rootDirectory);
     return (Rule) getTarget("//" + packageName + ":" + ruleName);
   }
@@ -924,7 +924,7 @@
   }
 
   protected Artifact getSourceArtifact(String name) {
-    return getSourceArtifact(new PathFragment(name), Root.asSourceRoot(rootDirectory));
+    return getSourceArtifact(PathFragment.create(name), Root.asSourceRoot(rootDirectory));
   }
 
   /**
@@ -959,7 +959,7 @@
    * used instead.
    */
   protected Artifact getBinArtifactWithNoOwner(String rootRelativePath) {
-    return getDerivedArtifact(new PathFragment(rootRelativePath),
+    return getDerivedArtifact(PathFragment.create(rootRelativePath),
         targetConfig.getBinDirectory(RepositoryName.MAIN),
         ActionsTestUtil.NULL_ARTIFACT_OWNER);
   }
@@ -1037,7 +1037,7 @@
    * #getGenfilesArtifact(String, ArtifactOwner)} or its convenience methods should be used instead.
    */
   protected Artifact getGenfilesArtifactWithNoOwner(String rootRelativePath) {
-    return getDerivedArtifact(new PathFragment(rootRelativePath),
+    return getDerivedArtifact(PathFragment.create(rootRelativePath),
         targetConfig.getGenfilesDirectory(RepositoryName.MAIN),
         ActionsTestUtil.NULL_ARTIFACT_OWNER);
   }
@@ -1150,7 +1150,7 @@
    * @param owner the artifact's owner.
    */
   protected Artifact getSharedArtifact(String rootRelativePath, ConfiguredTarget owner) {
-    return getDerivedArtifact(new PathFragment(rootRelativePath),
+    return getDerivedArtifact(PathFragment.create(rootRelativePath),
         targetConfig.getBinDirectory(RepositoryName.MAIN),
         new ConfiguredTargetKey(owner));
   }
diff --git a/src/test/java/com/google/devtools/build/lib/bazel/repository/StripPrefixedPathTest.java b/src/test/java/com/google/devtools/build/lib/bazel/repository/StripPrefixedPathTest.java
index f3ab3f1..d2ca3ac 100644
--- a/src/test/java/com/google/devtools/build/lib/bazel/repository/StripPrefixedPathTest.java
+++ b/src/test/java/com/google/devtools/build/lib/bazel/repository/StripPrefixedPathTest.java
@@ -35,7 +35,7 @@
   @Test
   public void testStrip() {
     StripPrefixedPath result = StripPrefixedPath.maybeDeprefix("foo/bar", Optional.of("foo"));
-    assertEquals(result.getPathFragment(), new PathFragment("bar"));
+    assertEquals(result.getPathFragment(), PathFragment.create("bar"));
     assertTrue(result.foundPrefix());
     assertFalse(result.skip());
 
@@ -53,13 +53,13 @@
   public void testAbsolute() {
     StripPrefixedPath result = StripPrefixedPath.maybeDeprefix(
         "/foo/bar", Optional.<String>absent());
-    assertThat(result.getPathFragment()).isEqualTo(new PathFragment("foo/bar"));
+    assertThat(result.getPathFragment()).isEqualTo(PathFragment.create("foo/bar"));
 
     result = StripPrefixedPath.maybeDeprefix("///foo/bar/baz", Optional.<String>absent());
-    assertThat(result.getPathFragment()).isEqualTo(new PathFragment("foo/bar/baz"));
+    assertThat(result.getPathFragment()).isEqualTo(PathFragment.create("foo/bar/baz"));
 
     result = StripPrefixedPath.maybeDeprefix("/foo/bar/baz", Optional.of("/foo"));
-    assertThat(result.getPathFragment()).isEqualTo(new PathFragment("bar/baz"));
+    assertThat(result.getPathFragment()).isEqualTo(PathFragment.create("bar/baz"));
   }
 
   @Test
@@ -69,19 +69,19 @@
     }
     StripPrefixedPath result = StripPrefixedPath.maybeDeprefix(
         "c:/foo/bar", Optional.<String>absent());
-    assertThat(result.getPathFragment()).isEqualTo(new PathFragment("foo/bar"));
+    assertThat(result.getPathFragment()).isEqualTo(PathFragment.create("foo/bar"));
   }
 
   @Test
   public void testNormalize() {
     StripPrefixedPath result = StripPrefixedPath.maybeDeprefix(
         "../bar", Optional.<String>absent());
-    assertThat(result.getPathFragment()).isEqualTo(new PathFragment("../bar"));
+    assertThat(result.getPathFragment()).isEqualTo(PathFragment.create("../bar"));
 
     result = StripPrefixedPath.maybeDeprefix("foo/../baz", Optional.<String>absent());
-    assertThat(result.getPathFragment()).isEqualTo(new PathFragment("baz"));
+    assertThat(result.getPathFragment()).isEqualTo(PathFragment.create("baz"));
 
     result = StripPrefixedPath.maybeDeprefix("foo/../baz", Optional.of("foo"));
-    assertThat(result.getPathFragment()).isEqualTo(new PathFragment("baz"));
+    assertThat(result.getPathFragment()).isEqualTo(PathFragment.create("baz"));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/bazel/rules/genrule/GenRuleConfiguredTargetTest.java b/src/test/java/com/google/devtools/build/lib/bazel/rules/genrule/GenRuleConfiguredTargetTest.java
index b5f18a7..7d32380 100644
--- a/src/test/java/com/google/devtools/build/lib/bazel/rules/genrule/GenRuleConfiguredTargetTest.java
+++ b/src/test/java/com/google/devtools/build/lib/bazel/rules/genrule/GenRuleConfiguredTargetTest.java
@@ -106,7 +106,7 @@
     createFiles();
     ConfiguredTarget z = getConfiguredTarget("//hello:z");
     Artifact y = getOnlyElement(getFilesToBuild(z));
-    assertEquals(new PathFragment("hello/x/y"), y.getRootRelativePath());
+    assertEquals(PathFragment.create("hello/x/y"), y.getRootRelativePath());
   }
 
   @Test
@@ -115,8 +115,8 @@
     ConfiguredTarget z = getConfiguredTarget("//hello:w");
     List<Artifact> files = getFilesToBuild(z).toList();
     assertThat(files).hasSize(2);
-    assertEquals(new PathFragment("hello/a/b"), files.get(0).getRootRelativePath());
-    assertEquals(new PathFragment("hello/c/d"), files.get(1).getRootRelativePath());
+    assertEquals(PathFragment.create("hello/a/b"), files.get(0).getRootRelativePath());
+    assertEquals(PathFragment.create("hello/c/d"), files.get(1).getRootRelativePath());
   }
 
   @Test
@@ -236,10 +236,10 @@
     FileConfiguredTarget bazOutTarget = getFileConfiguredTarget("//foo:baz_out.txt");
     Action bazAction = getGeneratingAction(bazOutTarget.getArtifact());
     Artifact barOut = bazAction.getInputs().iterator().next();
-    assertTrue(barOut.getExecPath().endsWith(new PathFragment("foo/bar_out.txt")));
+    assertTrue(barOut.getExecPath().endsWith(PathFragment.create("foo/bar_out.txt")));
     Action barAction = getGeneratingAction(barOut);
     Artifact barIn = barAction.getInputs().iterator().next();
-    assertTrue(barIn.getExecPath().endsWith(new PathFragment("foo/bar_in.txt")));
+    assertTrue(barIn.getExecPath().endsWith(PathFragment.create("foo/bar_in.txt")));
   }
 
   /** Ensure that variable $(@D) gets expanded correctly in the genrule cmd. */
@@ -279,7 +279,7 @@
     getConfiguredTarget("//foo:bar");
 
     Artifact barOut = bazAction.getInputs().iterator().next();
-    assertTrue(barOut.getExecPath().endsWith(new PathFragment("foo/bar/bar_out.txt")));
+    assertTrue(barOut.getExecPath().endsWith(PathFragment.create("foo/bar/bar_out.txt")));
     SpawnAction barAction = (SpawnAction) getGeneratingAction(barOut);
     String barExpected = "touch " + barOut.getExecPath().getParentDirectory().getPathString();
     assertCommandEquals(barExpected, barAction.getArguments().get(2));
diff --git a/src/test/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemanticsTest.java b/src/test/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemanticsTest.java
index 529053b..6758e80 100644
--- a/src/test/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemanticsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemanticsTest.java
@@ -30,15 +30,21 @@
   @Test
   public void testFindingResources() {
     BazelJavaSemantics semantics = BazelJavaSemantics.INSTANCE;
-    assertEquals(PathFragment.EMPTY_FRAGMENT,
-        semantics.getDefaultJavaResourcePath(new PathFragment("x/y/src/main/resources")));
-    assertEquals(new PathFragment("foo"),
-        semantics.getDefaultJavaResourcePath(new PathFragment("x/y/src/main/resources/foo")));
-    assertEquals(new PathFragment("foo"),
-        semantics.getDefaultJavaResourcePath(new PathFragment("java/x/y/src/main/resources/foo")));
-    assertEquals(new PathFragment("foo/java/bar"),
-        semantics.getDefaultJavaResourcePath(new PathFragment("java/foo/java/bar")));
-    assertEquals(new PathFragment("foo/java/bar"),
-        semantics.getDefaultJavaResourcePath(new PathFragment("javatests/foo/java/bar")));
+    assertEquals(
+        PathFragment.EMPTY_FRAGMENT,
+        semantics.getDefaultJavaResourcePath(PathFragment.create("x/y/src/main/resources")));
+    assertEquals(
+        PathFragment.create("foo"),
+        semantics.getDefaultJavaResourcePath(PathFragment.create("x/y/src/main/resources/foo")));
+    assertEquals(
+        PathFragment.create("foo"),
+        semantics.getDefaultJavaResourcePath(
+            PathFragment.create("java/x/y/src/main/resources/foo")));
+    assertEquals(
+        PathFragment.create("foo/java/bar"),
+        semantics.getDefaultJavaResourcePath(PathFragment.create("java/foo/java/bar")));
+    assertEquals(
+        PathFragment.create("foo/java/bar"),
+        semantics.getDefaultJavaResourcePath(PathFragment.create("javatests/foo/java/bar")));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/buildtool/SymlinkForestTest.java b/src/test/java/com/google/devtools/build/lib/buildtool/SymlinkForestTest.java
index 3c93edc..31ba090 100644
--- a/src/test/java/com/google/devtools/build/lib/buildtool/SymlinkForestTest.java
+++ b/src/test/java/com/google/devtools/build/lib/buildtool/SymlinkForestTest.java
@@ -113,7 +113,7 @@
 
   @Test
   public void testLongestPathPrefix() {
-    PathFragment a = new PathFragment("A");
+    PathFragment a = PathFragment.create("A");
     assertEquals(a, longestPathPrefix("A/b", "A", "B")); // simple parent
     assertEquals(a, longestPathPrefix("A", "A", "B")); // self
     assertEquals(a.getRelative("B"), longestPathPrefix("A/B/c", "A", "A/B"));  // want longest
@@ -151,7 +151,7 @@
       createDirectoryAndParents(repoRoot.getRelative(pkg));
       FileSystemUtils.createEmptyFile(repoRoot.getRelative(pkg).getChild("file"));
     }
-    return PackageIdentifier.create(RepositoryName.create("@" + repo), new PathFragment(pkg));
+    return PackageIdentifier.create(RepositoryName.create("@" + repo), PathFragment.create(pkg));
   }
 
   private void assertLinksTo(Path fromRoot, Path toRoot, String relpart) throws IOException {
diff --git a/src/test/java/com/google/devtools/build/lib/cmdline/LabelTest.java b/src/test/java/com/google/devtools/build/lib/cmdline/LabelTest.java
index b98d618..74e1248 100644
--- a/src/test/java/com/google/devtools/build/lib/cmdline/LabelTest.java
+++ b/src/test/java/com/google/devtools/build/lib/cmdline/LabelTest.java
@@ -62,7 +62,7 @@
   }
 
   private static String parseCommandLine(String label, String prefix) throws LabelSyntaxException {
-    return Label.parseCommandLineLabel(label, new PathFragment(prefix)).toString();
+    return Label.parseCommandLineLabel(label, PathFragment.create(prefix)).toString();
   }
 
   @Test
@@ -144,43 +144,43 @@
 
   @Test
   public void testGetRelativeWithDifferentRepo() throws Exception {
-    PackageIdentifier packageId = PackageIdentifier.create("@repo", new PathFragment("foo"));
+    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
     Label base = Label.create(packageId, "bar");
 
     Label relative = base.getRelative("@remote//x:y");
 
     assertEquals(RepositoryName.create("@remote"), relative.getPackageIdentifier().getRepository());
-    assertEquals(new PathFragment("x"), relative.getPackageFragment());
+    assertEquals(PathFragment.create("x"), relative.getPackageFragment());
     assertEquals("y", relative.getName());
   }
 
   @Test
   public void testGetRelativeWithRepoLocalAbsoluteLabel() throws Exception {
-    PackageIdentifier packageId = PackageIdentifier.create("@repo", new PathFragment("foo"));
+    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
     Label base = Label.create(packageId, "bar");
 
     Label relative = base.getRelative("//x:y");
 
     assertEquals(packageId.getRepository(), relative.getPackageIdentifier().getRepository());
-    assertEquals(new PathFragment("x"), relative.getPackageFragment());
+    assertEquals(PathFragment.create("x"), relative.getPackageFragment());
     assertEquals("y", relative.getName());
   }
 
   @Test
   public void testGetRelativeWithLocalRepoRelativeLabel() throws Exception {
-    PackageIdentifier packageId = PackageIdentifier.create("@repo", new PathFragment("foo"));
+    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
     Label base = Label.create(packageId, "bar");
 
     Label relative = base.getRelative(":y");
 
     assertEquals(packageId.getRepository(), relative.getPackageIdentifier().getRepository());
-    assertEquals(new PathFragment("foo"), relative.getPackageFragment());
+    assertEquals(PathFragment.create("foo"), relative.getPackageFragment());
     assertEquals("y", relative.getName());
   }
 
   @Test
   public void testGetRelativeWithRepoAndReservedPackage() throws Exception {
-    PackageIdentifier packageId = PackageIdentifier.create("@repo", new PathFragment("foo"));
+    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
     Label base = Label.create(packageId, "bar");
 
     Label relative = base.getRelative("//conditions:default");
@@ -193,13 +193,13 @@
 
   @Test
   public void testGetRelativeWithRemoteRepoToDefaultRepo() throws Exception {
-    PackageIdentifier packageId = PackageIdentifier.create("@repo", new PathFragment("foo"));
+    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
     Label base = Label.create(packageId, "bar");
 
     Label relative = base.getRelative("@//x:y");
 
     assertEquals(RepositoryName.create("@"), relative.getPackageIdentifier().getRepository());
-    assertEquals(new PathFragment("x"), relative.getPackageFragment());
+    assertEquals(PathFragment.create("x"), relative.getPackageFragment());
     assertEquals("y", relative.getName());
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/cmdline/PackageIdentifierTest.java b/src/test/java/com/google/devtools/build/lib/cmdline/PackageIdentifierTest.java
index a19ef4b..f01a48c 100644
--- a/src/test/java/com/google/devtools/build/lib/cmdline/PackageIdentifierTest.java
+++ b/src/test/java/com/google/devtools/build/lib/cmdline/PackageIdentifierTest.java
@@ -40,7 +40,7 @@
     assertThat(fooA.getRepository().strippedName()).isEqualTo("foo");
     assertThat(fooA.getPackageFragment().getPathString()).isEqualTo("a");
     assertThat(fooA.getRepository().getSourceRoot()).isEqualTo(
-        new PathFragment("external/foo"));
+        PathFragment.create("external/foo"));
 
     PackageIdentifier absoluteA = PackageIdentifier.parse("//a");
     assertThat(absoluteA.getRepository().strippedName()).isEqualTo("");
@@ -58,18 +58,18 @@
 
   @Test
   public void testToString() throws Exception {
-    PackageIdentifier local = PackageIdentifier.create("", new PathFragment("bar/baz"));
+    PackageIdentifier local = PackageIdentifier.create("", PathFragment.create("bar/baz"));
     assertEquals("bar/baz", local.toString());
-    PackageIdentifier external = PackageIdentifier.create("@foo", new PathFragment("bar/baz"));
+    PackageIdentifier external = PackageIdentifier.create("@foo", PathFragment.create("bar/baz"));
     assertEquals("@foo//bar/baz", external.toString());
   }
 
   @Test
   public void testCompareTo() throws Exception {
-    PackageIdentifier foo1 = PackageIdentifier.create("@foo", new PathFragment("bar/baz"));
-    PackageIdentifier foo2 = PackageIdentifier.create("@foo", new PathFragment("bar/baz"));
-    PackageIdentifier foo3 = PackageIdentifier.create("@foo", new PathFragment("bar/bz"));
-    PackageIdentifier bar = PackageIdentifier.create("@bar", new PathFragment("bar/baz"));
+    PackageIdentifier foo1 = PackageIdentifier.create("@foo", PathFragment.create("bar/baz"));
+    PackageIdentifier foo2 = PackageIdentifier.create("@foo", PathFragment.create("bar/baz"));
+    PackageIdentifier foo3 = PackageIdentifier.create("@foo", PathFragment.create("bar/bz"));
+    PackageIdentifier bar = PackageIdentifier.create("@bar", PathFragment.create("bar/baz"));
     assertEquals(0, foo1.compareTo(foo2));
     assertThat(foo1.compareTo(foo3)).isLessThan(0);
     assertThat(foo1.compareTo(bar)).isGreaterThan(0);
@@ -78,12 +78,12 @@
   @Test
   public void testInvalidPackageName() throws Exception {
     // This shouldn't throw an exception, package names aren't validated.
-    PackageIdentifier.create("@foo", new PathFragment("bar.baz"));
+    PackageIdentifier.create("@foo", PathFragment.create("bar.baz"));
   }
 
   @Test
   public void testSerialization() throws Exception {
-    PackageIdentifier inId = PackageIdentifier.create("@foo", new PathFragment("bar/baz"));
+    PackageIdentifier inId = PackageIdentifier.create("@foo", PathFragment.create("bar/baz"));
     ByteArrayOutputStream data = new ByteArrayOutputStream();
     ObjectOutputStream out = new ObjectOutputStream(data);
     out.writeObject(inId);
@@ -95,16 +95,16 @@
   @Test
   public void testPackageFragmentEquality() throws Exception {
     // Make sure package fragments are canonicalized.
-    PackageIdentifier p1 = PackageIdentifier.create("@whatever", new PathFragment("foo/bar"));
-    PackageIdentifier p2 = PackageIdentifier.create("@whatever", new PathFragment("foo/bar"));
+    PackageIdentifier p1 = PackageIdentifier.create("@whatever", PathFragment.create("foo/bar"));
+    PackageIdentifier p2 = PackageIdentifier.create("@whatever", PathFragment.create("foo/bar"));
     assertSame(p2.getPackageFragment(), p1.getPackageFragment());
   }
 
   @Test
   public void testRunfilesDir() throws Exception {
-    assertThat(PackageIdentifier.create("@foo", new PathFragment("bar/baz")).getRunfilesPath())
-        .isEqualTo(new PathFragment("../foo/bar/baz"));
-    assertThat(PackageIdentifier.create("@", new PathFragment("bar/baz")).getRunfilesPath())
-        .isEqualTo(new PathFragment("bar/baz"));
+    assertThat(PackageIdentifier.create("@foo", PathFragment.create("bar/baz")).getRunfilesPath())
+        .isEqualTo(PathFragment.create("../foo/bar/baz"));
+    assertThat(PackageIdentifier.create("@", PathFragment.create("bar/baz")).getRunfilesPath())
+        .isEqualTo(PathFragment.create("bar/baz"));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/cmdline/RepositoryNameTest.java b/src/test/java/com/google/devtools/build/lib/cmdline/RepositoryNameTest.java
index 9a39bbf..6970b5e 100644
--- a/src/test/java/com/google/devtools/build/lib/cmdline/RepositoryNameTest.java
+++ b/src/test/java/com/google/devtools/build/lib/cmdline/RepositoryNameTest.java
@@ -60,7 +60,7 @@
   @Test
   public void testRunfilesDir() throws Exception {
     assertThat(RepositoryName.create("@foo").getRunfilesPath())
-        .isEqualTo(new PathFragment("../foo"));
+        .isEqualTo(PathFragment.create("../foo"));
     assertThat(RepositoryName.create("@").getRunfilesPath())
         .isEqualTo(PathFragment.EMPTY_FRAGMENT);
     assertThat(RepositoryName.create("").getRunfilesPath())
diff --git a/src/test/java/com/google/devtools/build/lib/events/EventTestTemplate.java b/src/test/java/com/google/devtools/build/lib/events/EventTestTemplate.java
index e505586..136c7b9 100644
--- a/src/test/java/com/google/devtools/build/lib/events/EventTestTemplate.java
+++ b/src/test/java/com/google/devtools/build/lib/events/EventTestTemplate.java
@@ -29,7 +29,7 @@
   @Before
   public final void createLocations() throws Exception  {
     String message = "This is not an error message.";
-    path = new PathFragment("/path/to/workspace/my/sample/path.txt");
+    path = PathFragment.create("/path/to/workspace/my/sample/path.txt");
 
     location = Location.fromPathAndStartColumn(path, 21, 31, new LineAndColumn(3, 4));
 
diff --git a/src/test/java/com/google/devtools/build/lib/events/LocationTest.java b/src/test/java/com/google/devtools/build/lib/events/LocationTest.java
index 23ed25e..5c1c887 100644
--- a/src/test/java/com/google/devtools/build/lib/events/LocationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/events/LocationTest.java
@@ -39,13 +39,20 @@
   @Test
   public void testPrintRelative() throws Exception {
     Location location = Location.fromPathFragment(path);
-    assertEquals("/path/to/workspace/my/sample/path.txt:1",
-        location.print(new PathFragment("/some/other/path"), new PathFragment("baz")));
-    assertEquals("new/sample/path.txt:1",
-        location.print(new PathFragment("/path/to/workspace/my"), new PathFragment("new")));
-    assertEquals("new/path.txt:1",
-        location.print(new PathFragment("/path/to/workspace/my/sample"), new PathFragment("new")));
-    assertEquals("new:1", location.print(new PathFragment("/path/to/workspace/my/sample/path.txt"),
-        new PathFragment("new")));
+    assertEquals(
+        "/path/to/workspace/my/sample/path.txt:1",
+        location.print(PathFragment.create("/some/other/path"), PathFragment.create("baz")));
+    assertEquals(
+        "new/sample/path.txt:1",
+        location.print(PathFragment.create("/path/to/workspace/my"), PathFragment.create("new")));
+    assertEquals(
+        "new/path.txt:1",
+        location.print(
+            PathFragment.create("/path/to/workspace/my/sample"), PathFragment.create("new")));
+    assertEquals(
+        "new:1",
+        location.print(
+            PathFragment.create("/path/to/workspace/my/sample/path.txt"),
+            PathFragment.create("new")));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/exec/ParameterFileTest.java b/src/test/java/com/google/devtools/build/lib/exec/ParameterFileTest.java
index 491cf09..5c97c2a 100644
--- a/src/test/java/com/google/devtools/build/lib/exec/ParameterFileTest.java
+++ b/src/test/java/com/google/devtools/build/lib/exec/ParameterFileTest.java
@@ -34,8 +34,11 @@
 
   @Test
   public void testDerive() {
-    assertEquals(new PathFragment("a/b-2.params"),
-        ParameterFile.derivePath(new PathFragment("a/b")));
-    assertEquals(new PathFragment("b-2.params"), ParameterFile.derivePath(new PathFragment("b")));
+    assertEquals(
+        PathFragment.create("a/b-2.params"),
+        ParameterFile.derivePath(PathFragment.create("a/b")));
+    assertEquals(
+        PathFragment.create("b-2.params"),
+        ParameterFile.derivePath(PathFragment.create("b")));
   }
 }
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 fdfa655..5b6db72 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
@@ -74,14 +74,14 @@
     Artifact artifact =
         new Artifact(fs.getPath("/root/dir/file"), Root.asSourceRoot(fs.getPath("/root")));
     Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(artifact).build();
-    RunfilesSupplier supplier = new RunfilesSupplierImpl(new PathFragment("runfiles"), runfiles);
+    RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
     ActionInputFileCache mockCache = Mockito.mock(ActionInputFileCache.class);
     Mockito.when(mockCache.isFile(artifact)).thenReturn(true);
 
     expander.addRunfilesToInputs(inputMappings, supplier, mockCache);
     assertThat(inputMappings).hasSize(1);
     assertThat(inputMappings)
-        .containsEntry(new PathFragment("runfiles/workspace/dir/file"), artifact);
+        .containsEntry(PathFragment.create("runfiles/workspace/dir/file"), artifact);
   }
 
   @Test
@@ -89,7 +89,7 @@
     Artifact artifact =
         new Artifact(fs.getPath("/root/dir/file"), Root.asSourceRoot(fs.getPath("/root")));
     Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(artifact).build();
-    RunfilesSupplier supplier = new RunfilesSupplierImpl(new PathFragment("runfiles"), runfiles);
+    RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
     ActionInputFileCache mockCache = Mockito.mock(ActionInputFileCache.class);
     Mockito.when(mockCache.isFile(artifact)).thenReturn(false);
 
@@ -106,7 +106,7 @@
     Artifact artifact =
         new Artifact(fs.getPath("/root/dir/file"), Root.asSourceRoot(fs.getPath("/root")));
     Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(artifact).build();
-    RunfilesSupplier supplier = new RunfilesSupplierImpl(new PathFragment("runfiles"), runfiles);
+    RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
     ActionInputFileCache mockCache = Mockito.mock(ActionInputFileCache.class);
     Mockito.when(mockCache.isFile(artifact)).thenReturn(false);
 
@@ -114,7 +114,7 @@
     expander.addRunfilesToInputs(inputMappings, supplier, mockCache);
     assertThat(inputMappings).hasSize(1);
     assertThat(inputMappings)
-        .containsEntry(new PathFragment("runfiles/workspace/dir/file"), artifact);
+        .containsEntry(PathFragment.create("runfiles/workspace/dir/file"), artifact);
   }
 
   @Test
@@ -127,7 +127,7 @@
         .addArtifact(artifact1)
         .addArtifact(artifact2)
         .build();
-    RunfilesSupplier supplier = new RunfilesSupplierImpl(new PathFragment("runfiles"), runfiles);
+    RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
     ActionInputFileCache mockCache = Mockito.mock(ActionInputFileCache.class);
     Mockito.when(mockCache.isFile(artifact1)).thenReturn(true);
     Mockito.when(mockCache.isFile(artifact2)).thenReturn(true);
@@ -135,9 +135,9 @@
     expander.addRunfilesToInputs(inputMappings, supplier, mockCache);
     assertThat(inputMappings).hasSize(2);
     assertThat(inputMappings)
-        .containsEntry(new PathFragment("runfiles/workspace/dir/file"), artifact1);
+        .containsEntry(PathFragment.create("runfiles/workspace/dir/file"), artifact1);
     assertThat(inputMappings)
-        .containsEntry(new PathFragment("runfiles/workspace/dir/baz"), artifact2);
+        .containsEntry(PathFragment.create("runfiles/workspace/dir/baz"), artifact2);
   }
 
   @Test
@@ -145,15 +145,15 @@
     Artifact artifact =
         new Artifact(fs.getPath("/root/dir/file"), Root.asSourceRoot(fs.getPath("/root")));
     Runfiles runfiles = new Runfiles.Builder("workspace")
-        .addSymlink(new PathFragment("symlink"), artifact).build();
-    RunfilesSupplier supplier = new RunfilesSupplierImpl(new PathFragment("runfiles"), runfiles);
+        .addSymlink(PathFragment.create("symlink"), artifact).build();
+    RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
     ActionInputFileCache mockCache = Mockito.mock(ActionInputFileCache.class);
     Mockito.when(mockCache.isFile(artifact)).thenReturn(true);
 
     expander.addRunfilesToInputs(inputMappings, supplier, mockCache);
     assertThat(inputMappings).hasSize(1);
     assertThat(inputMappings)
-        .containsEntry(new PathFragment("runfiles/workspace/symlink"), artifact);
+        .containsEntry(PathFragment.create("runfiles/workspace/symlink"), artifact);
   }
 
   @Test
@@ -161,19 +161,19 @@
     Artifact artifact =
         new Artifact(fs.getPath("/root/dir/file"), Root.asSourceRoot(fs.getPath("/root")));
     Runfiles runfiles = new Runfiles.Builder("workspace")
-        .addRootSymlink(new PathFragment("symlink"), artifact).build();
-    RunfilesSupplier supplier = new RunfilesSupplierImpl(new PathFragment("runfiles"), runfiles);
+        .addRootSymlink(PathFragment.create("symlink"), artifact).build();
+    RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
     ActionInputFileCache mockCache = Mockito.mock(ActionInputFileCache.class);
     Mockito.when(mockCache.isFile(artifact)).thenReturn(true);
 
     expander.addRunfilesToInputs(inputMappings, supplier, mockCache);
     assertThat(inputMappings).hasSize(2);
-    assertThat(inputMappings).containsEntry(new PathFragment("runfiles/symlink"), artifact);
+    assertThat(inputMappings).containsEntry(PathFragment.create("runfiles/symlink"), artifact);
     // If there's no other entry, Runfiles adds an empty file in the workspace to make sure the
     // directory gets created.
     assertThat(inputMappings)
         .containsEntry(
-            new PathFragment("runfiles/workspace/.runfile"), SpawnInputExpander.EMPTY_FILE);
+            PathFragment.create("runfiles/workspace/.runfile"), SpawnInputExpander.EMPTY_FILE);
   }
 
   @Test
@@ -200,7 +200,7 @@
     expander.parseFilesetManifest(inputMappings, artifact, "workspace");
     assertThat(inputMappings).hasSize(1);
     assertThat(inputMappings)
-        .containsEntry(new PathFragment("foo/bar"), ActionInputHelper.fromPath("/dir/file"));
+        .containsEntry(PathFragment.create("foo/bar"), ActionInputHelper.fromPath("/dir/file"));
   }
 
   @Test
@@ -218,9 +218,9 @@
     expander.parseFilesetManifest(inputMappings, artifact, "workspace");
     assertThat(inputMappings).hasSize(2);
     assertThat(inputMappings)
-        .containsEntry(new PathFragment("foo/bar"), ActionInputHelper.fromPath("/dir/file"));
+        .containsEntry(PathFragment.create("foo/bar"), ActionInputHelper.fromPath("/dir/file"));
     assertThat(inputMappings)
-        .containsEntry(new PathFragment("foo/baz"), ActionInputHelper.fromPath("/dir/file"));
+        .containsEntry(PathFragment.create("foo/baz"), ActionInputHelper.fromPath("/dir/file"));
   }
 
   @Test
@@ -237,6 +237,6 @@
     assertThat(inputMappings).hasSize(1);
     assertThat(inputMappings)
         .containsEntry(
-            new PathFragment("foo/bar"), ActionInputHelper.fromPath("/some"));
+            PathFragment.create("foo/bar"), ActionInputHelper.fromPath("/some"));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/packages/PackageFactoryTest.java b/src/test/java/com/google/devtools/build/lib/packages/PackageFactoryTest.java
index 3573827..7ab592e 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/PackageFactoryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/PackageFactoryTest.java
@@ -259,7 +259,7 @@
             "genrule(name='c', srcs=[], outs=['ao'], cmd=REPOSITORY_NAME + ' ' + PACKAGE_NAME)");
     Package pkg =
         packages.createPackage(
-            PackageIdentifier.create("@a", new PathFragment("b")), buildFile, events.reporter());
+            PackageIdentifier.create("@a", PathFragment.create("b")), buildFile, events.reporter());
     Rule c = pkg.getRule("c");
     assertThat(AggregatingAttributeMapper.of(c).get("cmd", Type.STRING)).isEqualTo("@a b");
   }
diff --git a/src/test/java/com/google/devtools/build/lib/packages/PackageGroupStaticInitializationTest.java b/src/test/java/com/google/devtools/build/lib/packages/PackageGroupStaticInitializationTest.java
index 404b7aa..f05709d 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/PackageGroupStaticInitializationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/PackageGroupStaticInitializationTest.java
@@ -88,7 +88,7 @@
   }
 
   private Package getPackage(String packageName) throws Exception {
-    PathFragment buildFileFragment = new PathFragment(packageName).getRelative("BUILD");
+    PathFragment buildFileFragment = PathFragment.create(packageName).getRelative("BUILD");
     Path buildFile = scratch.resolve(buildFileFragment.getPathString());
     return packages.createPackage(packageName, buildFile);
   }
diff --git a/src/test/java/com/google/devtools/build/lib/packages/PackageGroupTest.java b/src/test/java/com/google/devtools/build/lib/packages/PackageGroupTest.java
index 50ca268..55e8da9 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/PackageGroupTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/PackageGroupTest.java
@@ -154,7 +154,7 @@
   }
 
   private Package getPackage(String packageName) throws Exception {
-    PathFragment buildFileFragment = new PathFragment(packageName).getRelative("BUILD");
+    PathFragment buildFileFragment = PathFragment.create(packageName).getRelative("BUILD");
 
     Path buildFile = scratch.resolve(buildFileFragment.getPathString());
     return packages.createPackage(packageName, buildFile);
diff --git a/src/test/java/com/google/devtools/build/lib/packages/RelativePackageNameResolverTest.java b/src/test/java/com/google/devtools/build/lib/packages/RelativePackageNameResolverTest.java
index 9f2f9b6..fee2a7c 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/RelativePackageNameResolverTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/RelativePackageNameResolverTest.java
@@ -112,7 +112,7 @@
   }
 
   private void createResolver(String offset, boolean discardBuild) {
-    resolver = new RelativePackageNameResolver(new PathFragment(offset), discardBuild);
+    resolver = new RelativePackageNameResolver(PathFragment.create(offset), discardBuild);
   }
 
   private void assertResolvesTo(String relative, String expectedAbsolute) throws Exception {
diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/MockCcSupport.java b/src/test/java/com/google/devtools/build/lib/packages/util/MockCcSupport.java
index e2d13a0..ea92b17 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/util/MockCcSupport.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/util/MockCcSupport.java
@@ -603,7 +603,7 @@
     try {
       return PackageIdentifier.create(
           RepositoryName.create(TestConstants.TOOLS_REPOSITORY),
-          new PathFragment(TestConstants.TOOLS_REPOSITORY_PATH));
+          PathFragment.create(TestConstants.TOOLS_REPOSITORY_PATH));
     } catch (LabelSyntaxException e) {
       Verify.verify(false);
       throw new AssertionError();
diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/SubincludePreprocessor.java b/src/test/java/com/google/devtools/build/lib/packages/util/SubincludePreprocessor.java
index dd161a2..e9b4a9b 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/util/SubincludePreprocessor.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/util/SubincludePreprocessor.java
@@ -95,7 +95,8 @@
       return "";
     }
 
-    Path subinclude = buildFile.getParentDirectory().getRelative(new PathFragment(label.getName()));
+    Path subinclude =
+        buildFile.getParentDirectory().getRelative(PathFragment.create(label.getName()));
     return subinclude.getPathString();
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/pkgcache/IOExceptionsTest.java b/src/test/java/com/google/devtools/build/lib/pkgcache/IOExceptionsTest.java
index 9f5edaf..6472f01 100644
--- a/src/test/java/com/google/devtools/build/lib/pkgcache/IOExceptionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/pkgcache/IOExceptionsTest.java
@@ -79,7 +79,7 @@
 
   @Override
   protected FileSystem createFileSystem() {
-    return new InMemoryFileSystem(BlazeClock.instance(), new PathFragment(FS_ROOT)) {
+    return new InMemoryFileSystem(BlazeClock.instance(), PathFragment.create(FS_ROOT)) {
       @Override
       public FileStatus stat(Path path, boolean followSymlinks) throws IOException {
         String crash = crashMessage.apply(path);
diff --git a/src/test/java/com/google/devtools/build/lib/pkgcache/IncrementalLoadingTest.java b/src/test/java/com/google/devtools/build/lib/pkgcache/IncrementalLoadingTest.java
index de78d51..bc5800e 100644
--- a/src/test/java/com/google/devtools/build/lib/pkgcache/IncrementalLoadingTest.java
+++ b/src/test/java/com/google/devtools/build/lib/pkgcache/IncrementalLoadingTest.java
@@ -524,7 +524,7 @@
       Path path = workspace.getRelative(fileName);
       Preconditions.checkState(!path.exists());
       FileSystemUtils.createDirectoryAndParents(path.getParentDirectory());
-      path.createSymbolicLink(new PathFragment(target));
+      path.createSymbolicLink(PathFragment.create(target));
       changes.add(path);
     }
 
@@ -546,7 +546,7 @@
       Path symlink = workspace.getRelative(fileName);
       Preconditions.checkState(symlink.exists());
       symlink.delete();
-      symlink.createSymbolicLink(new PathFragment(newTarget));
+      symlink.createSymbolicLink(PathFragment.create(newTarget));
       changes.add(symlink);
     }
 
diff --git a/src/test/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunnerTest.java b/src/test/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunnerTest.java
index 9cf3254..4ca07f9 100644
--- a/src/test/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunnerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunnerTest.java
@@ -468,8 +468,8 @@
     tester.getWorkspace().getChild("broken").createDirectory();
 
     // Create a circular symlink.
-    tester.getWorkspace().getRelative(new PathFragment("broken/BUILD"))
-        .createSymbolicLink(new PathFragment("BUILD"));
+    tester.getWorkspace().getRelative(PathFragment.create("broken/BUILD"))
+        .createSymbolicLink(PathFragment.create("BUILD"));
 
     assertCircularSymlinksDuringTargetParsing("//broken/...");
   }
@@ -479,10 +479,10 @@
     tester.getWorkspace().getChild("broken").createDirectory();
 
     // Create a circular symlink.
-    tester.getWorkspace().getRelative(new PathFragment("broken/BUILD"))
-        .createSymbolicLink(new PathFragment("x"));
-    tester.getWorkspace().getRelative(new PathFragment("broken/x"))
-        .createSymbolicLink(new PathFragment("BUILD"));
+    tester.getWorkspace().getRelative(PathFragment.create("broken/BUILD"))
+        .createSymbolicLink(PathFragment.create("x"));
+    tester.getWorkspace().getRelative(PathFragment.create("broken/x"))
+        .createSymbolicLink(PathFragment.create("BUILD"));
 
     assertCircularSymlinksDuringTargetParsing("//broken/...");
   }
diff --git a/src/test/java/com/google/devtools/build/lib/pkgcache/TargetPatternEvaluatorIOTest.java b/src/test/java/com/google/devtools/build/lib/pkgcache/TargetPatternEvaluatorIOTest.java
index 3b63fbe..471f884 100644
--- a/src/test/java/com/google/devtools/build/lib/pkgcache/TargetPatternEvaluatorIOTest.java
+++ b/src/test/java/com/google/devtools/build/lib/pkgcache/TargetPatternEvaluatorIOTest.java
@@ -58,7 +58,7 @@
 
   @Override
   protected FileSystem createFileSystem() {
-    return new InMemoryFileSystem(BlazeClock.instance(), new PathFragment(FS_ROOT)) {
+    return new InMemoryFileSystem(BlazeClock.instance(), PathFragment.create(FS_ROOT)) {
       @Override
       public FileStatus stat(Path path, boolean followSymlinks) throws IOException {
         FileStatus defaultResult = super.stat(path, followSymlinks);
diff --git a/src/test/java/com/google/devtools/build/lib/pkgcache/TargetPatternEvaluatorTest.java b/src/test/java/com/google/devtools/build/lib/pkgcache/TargetPatternEvaluatorTest.java
index 33e736a..da003ad 100644
--- a/src/test/java/com/google/devtools/build/lib/pkgcache/TargetPatternEvaluatorTest.java
+++ b/src/test/java/com/google/devtools/build/lib/pkgcache/TargetPatternEvaluatorTest.java
@@ -143,7 +143,7 @@
 
   private void invalidate(String file) throws InterruptedException {
     skyframeExecutor.invalidateFilesUnderPathForTesting(reporter,
-        ModifiedFileSet.builder().modify(new PathFragment(file)).build(), rootDirectory);
+        ModifiedFileSet.builder().modify(PathFragment.create(file)).build(), rootDirectory);
   }
 
   private void invalidate(ModifiedFileSet modifiedFileSet) throws InterruptedException {
@@ -340,9 +340,9 @@
     scratch.file("nest/nest/BUILD",
         "cc_library(name = 'nested2', srcs = [ ])");
 
-    updateOffset(new PathFragment("nest"));
+    updateOffset(PathFragment.create("nest"));
     assertThat(parseList(":all")).containsExactlyElementsIn(labels("//nest:nested1"));
-    updateOffset(new PathFragment("nest/nest"));
+    updateOffset(PathFragment.create("nest/nest"));
     assertThat(parseList(":all")).containsExactlyElementsIn(labels("//nest/nest:nested2"));
   }
 
@@ -556,7 +556,7 @@
     scratch.file("x/z/BUILD", "cc_library(name='z')");
     setDeletedPackages(Sets.newHashSet(PackageIdentifier.createInMainRepo("x/y")));
 
-    parser.updateOffset(new PathFragment("x"));
+    parser.updateOffset(PathFragment.create("x"));
     assertEquals(Sets.newHashSet(Label.parseAbsolute("//x/z")),
         targetsToLabels(getFailFast(parser.parseTargetPattern(parsingListener, "...", false))));
   }
@@ -786,7 +786,7 @@
   public void testSetOffset() throws Exception {
     assertEquals("//foo:foo1", parseIndividualTarget("foo:foo1").toString());
 
-    parser.updateOffset(new PathFragment("foo"));
+    parser.updateOffset(PathFragment.create("foo"));
     assertEquals("//foo:foo1", parseIndividualTarget(":foo1").toString());
   }
 
@@ -970,7 +970,7 @@
     assertThat(parseList("//h/...")).containsExactlyElementsIn(labels("//h"));
 
     ModifiedFileSet modifiedFileSet = ModifiedFileSet.builder()
-        .modify(new PathFragment("h/i/j/BUILD")).build();
+        .modify(PathFragment.create("h/i/j/BUILD")).build();
     invalidate(modifiedFileSet);
 
     assertThat(parseList("//h/...")).containsExactly(Label.parseAbsolute("//h/i/j:j"),
@@ -991,11 +991,11 @@
 
     scratch.file("h/i/j/k/BUILD", "sh_library(name='l')");
     ModifiedFileSet modifiedFileSet = ModifiedFileSet.builder()
-        .modify(new PathFragment("h"))
-        .modify(new PathFragment("h/i"))
-        .modify(new PathFragment("h/i/j"))
-        .modify(new PathFragment("h/i/j/k"))
-        .modify(new PathFragment("h/i/j/k/BUILD"))
+        .modify(PathFragment.create("h"))
+        .modify(PathFragment.create("h/i"))
+        .modify(PathFragment.create("h/i/j"))
+        .modify(PathFragment.create("h/i/j/k"))
+        .modify(PathFragment.create("h/i/j/k/BUILD"))
         .build();
     invalidate(modifiedFileSet);
     reporter.addHandler(failFastHandler);
@@ -1007,7 +1007,7 @@
   public void testBrokenSymlinkRepaired() throws Exception {
     reporter.removeHandler(failFastHandler);
     Path tuv = scratch.dir("t/u/v");
-    tuv.getChild("BUILD").createSymbolicLink(new PathFragment("../../BUILD"));
+    tuv.getChild("BUILD").createSymbolicLink(PathFragment.create("../../BUILD"));
 
     try {
       parseList("//t/...");
@@ -1018,7 +1018,7 @@
 
     scratch.file("t/BUILD", "sh_library(name='t')");
     ModifiedFileSet modifiedFileSet = ModifiedFileSet.builder()
-        .modify(new PathFragment("t/BUILD"))
+        .modify(PathFragment.create("t/BUILD"))
         .build();
 
     invalidate(modifiedFileSet);
@@ -1033,7 +1033,7 @@
   public void testInfiniteTreeFromSymlinks() throws Exception {
     reporter.removeHandler(failFastHandler);
     Path ab = scratch.dir("a/b");
-    ab.getChild("c").createSymbolicLink(new PathFragment("../b"));
+    ab.getChild("c").createSymbolicLink(PathFragment.create("../b"));
     scratch.file("a/b/BUILD", "filegroup(name='g')");
     ResolvedTargets<Target> result = parseTargetPatternList(parser, parsingListener,
         ImmutableList.of("//a/b/..."), true);
@@ -1045,7 +1045,7 @@
   public void testSymlinkCycle() throws Exception {
     reporter.removeHandler(failFastHandler);
     Path ab = scratch.dir("a/b");
-    ab.getChild("c").createSymbolicLink(new PathFragment("c"));
+    ab.getChild("c").createSymbolicLink(PathFragment.create("c"));
     scratch.file("a/b/BUILD", "filegroup(name='g')");
     ResolvedTargets<Target> result = parseTargetPatternList(parser, parsingListener,
         ImmutableList.of("//a/b/..."), true);
@@ -1060,13 +1060,13 @@
     scratch.dir("from-c");
     scratch.file("from-c/BUILD", "filegroup(name = 'from-c')");
     Path ab = scratch.dir("a/b");
-    ab.getChild("symlink").createSymbolicLink(new PathFragment("../../from-b"));
+    ab.getChild("symlink").createSymbolicLink(PathFragment.create("../../from-b"));
     scratch.dir("a/b/not-a-symlink");
     scratch.file("a/b/not-a-symlink/BUILD", "filegroup(name = 'not-a-symlink')");
     scratch.file(
         "a/b/DONT_FOLLOW_SYMLINKS_WHEN_TRAVERSING_THIS_DIRECTORY_VIA_A_RECURSIVE_TARGET_PATTERN");
     Path ac = scratch.dir("a/c");
-    ac.getChild("symlink").createSymbolicLink(new PathFragment("../../from-c"));
+    ac.getChild("symlink").createSymbolicLink(PathFragment.create("../../from-c"));
     ResolvedTargets<Target> result = parseTargetPatternList(parser, parsingListener,
         ImmutableList.of("//a/..."), true);
     assertThat(targetsToLabels(result.getTargets())).containsExactly(
diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidLibraryTest.java
index e0789e2..7e874d4 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidLibraryTest.java
@@ -1142,21 +1142,21 @@
         ImmutableList.of(
             SourceDirectory.fromSourceRoot(
                 rootDirectory.asFragment(),
-                new PathFragment("java/android/assets")),
+                PathFragment.create("java/android/assets")),
             SourceDirectory.fromRoot(
                 targetConfig.getGenfilesDirectory(RepositoryName.MAIN),
-                new PathFragment("java/android/assets"))),
+                PathFragment.create("java/android/assets"))),
         provider.getAssetDirs());
     assertEquals(
         ImmutableList.of(
             SourceDirectory.fromSourceRoot(
                 rootDirectory.asFragment(),
-                new PathFragment("java/android/res"))),
+                PathFragment.create("java/android/res"))),
         provider.getResourceDirs());
 
     assertEquals(ImmutableList.of(SourceDirectory.fromSourceRoot(
         rootDirectory.asFragment(),
-        new PathFragment("java/android")
+        PathFragment.create("java/android")
     )), provider.getIdlImports());
 
     Set<Artifact> artifactClosure = actionsTestUtil().artifactClosureOf(getFilesToBuild(target));
@@ -1193,11 +1193,13 @@
         ImmutableList.of(
             SourceDirectory.fromSourceRoot(
                 rootDirectory.asFragment(),
-                new PathFragment("research/handwriting/java/com/google/research/handwriting/assets")
+                PathFragment.create(
+                    "research/handwriting/java/com/google/research/handwriting/assets")
             ),
             SourceDirectory.fromRoot(
                 targetConfig.getGenfilesDirectory(RepositoryName.MAIN),
-                new PathFragment("research/handwriting/java/com/google/research/handwriting/assets")
+                PathFragment.create(
+                    "research/handwriting/java/com/google/research/handwriting/assets")
             )
         ),
         provider.getAssetDirs());
@@ -1205,14 +1207,14 @@
         ImmutableList.of(
             SourceDirectory.fromSourceRoot(
                 rootDirectory.asFragment(),
-                new PathFragment("research/handwriting/java/com/google/research/handwriting/res")
+                PathFragment.create("research/handwriting/java/com/google/research/handwriting/res")
             )
         ),
         provider.getResourceDirs());
 
     assertEquals(ImmutableList.of(SourceDirectory.fromSourceRoot(
         rootDirectory.asFragment(),
-        new PathFragment("research/handwriting/java/com/google/research/handwriting")
+        PathFragment.create("research/handwriting/java/com/google/research/handwriting")
     )), provider.getIdlImports());
 
     Set<Artifact> artifactClosure = actionsTestUtil().artifactClosureOf(getFilesToBuild(target));
@@ -1252,17 +1254,17 @@
         ImmutableList.of(
             SourceDirectory.fromSourceRoot(
                 rootDirectory.asFragment(),
-                new PathFragment("java/android/assets")),
+                PathFragment.create("java/android/assets")),
             SourceDirectory.fromRoot(
                 targetConfig.getGenfilesDirectory(RepositoryName.MAIN),
-                new PathFragment("java/android/assets"))
+                PathFragment.create("java/android/assets"))
         ),
         provider.getAssetDirs());
     assertEquals(
         ImmutableList.of(
             SourceDirectory.fromSourceRoot(
                 rootDirectory.asFragment(),
-                new PathFragment("java/android/res"))
+                PathFragment.create("java/android/res"))
         ),
         provider.getResourceDirs());
 
@@ -1270,10 +1272,10 @@
         ImmutableList.of(
             SourceDirectory.fromSourceRoot(
                 rootDirectory.asFragment(),
-                new PathFragment("java/android")),
+                PathFragment.create("java/android")),
             SourceDirectory.fromRoot(
                 targetConfig.getGenfilesDirectory(RepositoryName.MAIN),
-                new PathFragment("java/android"))
+                PathFragment.create("java/android"))
         ),
         provider.getIdlImports());
 
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcCommonTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcCommonTest.java
index e0fc844..4f5b63e 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcCommonTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcCommonTest.java
@@ -410,7 +410,7 @@
     String includesRoot = "bang/bang_includes";
     assertThat(foo.getProvider(CppCompilationContext.class).getSystemIncludeDirs())
         .containsAllOf(
-            new PathFragment(includesRoot),
+            PathFragment.create(includesRoot),
             targetConfig.getGenfilesFragment().getRelative(includesRoot));
   }
 
@@ -436,7 +436,7 @@
     List<PathFragment> expected =
         new ImmutableList.Builder<PathFragment>()
             .addAll(noIncludes.getProvider(CppCompilationContext.class).getSystemIncludeDirs())
-            .add(new PathFragment(includesRoot))
+            .add(PathFragment.create(includesRoot))
             .add(targetConfig.getGenfilesFragment().getRelative(includesRoot))
             .build();
     assertThat(foo.getProvider(CppCompilationContext.class).getSystemIncludeDirs())
@@ -548,7 +548,7 @@
     getSkyframeExecutor()
         .invalidateFilesUnderPathForTesting(
             reporter,
-            new ModifiedFileSet.Builder().modify(new PathFragment("WORKSPACE")).build(),
+            new ModifiedFileSet.Builder().modify(PathFragment.create("WORKSPACE")).build(),
             rootDirectory);
     FileSystemUtils.createDirectoryAndParents(scratch.resolve("/foo/bar"));
     scratch.file("/foo/WORKSPACE", "workspace(name = 'pkg')");
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java
index b80e00e..b87410c 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java
@@ -58,8 +58,8 @@
  */
 @RunWith(JUnit4.class)
 public class CcLibraryConfiguredTargetTest extends BuildViewTestCase {
-  private static final PathFragment STL_CPPMAP = new PathFragment("stl.cppmap");
-  private static final PathFragment CROSSTOOL_CPPMAP = new PathFragment("crosstool.cppmap");
+  private static final PathFragment STL_CPPMAP = PathFragment.create("stl.cppmap");
+  private static final PathFragment CROSSTOOL_CPPMAP = PathFragment.create("crosstool.cppmap");
 
   @Before
   public final void createFiles() throws Exception {
@@ -501,7 +501,7 @@
     List<String> names = new ArrayList<>();
     for (String flag : input) {
       if (CppFileTypes.CPP_MODULE.matches(flag)) {
-        names.add(new PathFragment(flag).getBaseName());
+        names.add(PathFragment.create(flag).getBaseName());
       }
     }
     return names;
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeaturesTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeaturesTest.java
index 7249401..71020d9 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeaturesTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeaturesTest.java
@@ -1209,7 +1209,7 @@
                 "   implies: 'action-a'",
                 "}")
             .getFeatureConfiguration("activates-action-a");
-    PathFragment crosstoolPath = new PathFragment("crosstool/");
+    PathFragment crosstoolPath = PathFragment.create("crosstool/");
     PathFragment toolPath = configuration.getToolForAction("action-a").getToolPath(crosstoolPath);
     assertThat(toolPath.toString()).isEqualTo("crosstool/toolchain/a");
   }
@@ -1251,7 +1251,7 @@
             "  implies: 'action-a'",
             "}");
 
-    PathFragment crosstoolPath = new PathFragment("crosstool/");
+    PathFragment crosstoolPath = PathFragment.create("crosstool/");
 
     FeatureConfiguration featureAConfiguration =
         toolchainFeatures.getFeatureConfiguration("feature-a", "activates-action-a");
@@ -1310,7 +1310,7 @@
             "  implies: 'action-a'",
             "}");
 
-    PathFragment crosstoolPath = new PathFragment("crosstool/");
+    PathFragment crosstoolPath = PathFragment.create("crosstool/");
 
     FeatureConfiguration noFeaturesConfiguration =
         toolchainFeatures.getFeatureConfiguration("activates-action-a");
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 2889e32..1b38da1 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
@@ -254,8 +254,8 @@
   @Test
   public void testComputeKeyNonStatic() throws Exception {
     final RuleContext ruleContext = createDummyRuleContext();
-    final PathFragment exeOutputPath = new PathFragment("dummyRuleContext/output/path");
-    final PathFragment dynamicOutputPath = new PathFragment("dummyRuleContext/output/path.so");
+    final PathFragment exeOutputPath = PathFragment.create("dummyRuleContext/output/path");
+    final PathFragment dynamicOutputPath = PathFragment.create("dummyRuleContext/output/path.so");
     final Artifact staticOutputFile = getBinArtifactWithNoOwner(exeOutputPath.getPathString());
     final Artifact dynamicOutputFile = getBinArtifactWithNoOwner(dynamicOutputPath.getPathString());
     final Artifact oFile = getSourceArtifact("cc/a.o");
@@ -286,7 +286,7 @@
             builder.setNativeDeps((i & 4) == 0);
             builder.setUseTestOnlyFlags((i & 8) == 0);
             builder.setFake((i & 16) == 0);
-            builder.setRuntimeSolibDir((i & 32) == 0 ? null : new PathFragment("so1"));
+            builder.setRuntimeSolibDir((i & 32) == 0 ? null : PathFragment.create("so1"));
             builder.setFeatureConfiguration(featureConfiguration);
 
             return builder.build();
@@ -301,8 +301,8 @@
   @Test
   public void testComputeKeyStatic() throws Exception {
     final RuleContext ruleContext = createDummyRuleContext();
-    final PathFragment staticOutputPath = new PathFragment("dummyRuleContext/output/path.a");
-    final PathFragment dynamicOutputPath = new PathFragment("dummyRuleContext/output/path.so");
+    final PathFragment staticOutputPath = PathFragment.create("dummyRuleContext/output/path.a");
+    final PathFragment dynamicOutputPath = PathFragment.create("dummyRuleContext/output/path.so");
     final Artifact staticOutputFile = getBinArtifactWithNoOwner(staticOutputPath.getPathString());
     final Artifact dynamicOutputFile = getBinArtifactWithNoOwner(dynamicOutputPath.getPathString());
     final Artifact oFile = getSourceArtifact("cc/a.o");
@@ -336,11 +336,11 @@
   public void testCommandLineSplitting() throws Exception {
     RuleContext ruleContext = createDummyRuleContext();
     Artifact output = getDerivedArtifact(
-        new PathFragment("output/path.xyz"), getTargetConfiguration().getBinDirectory(
+        PathFragment.create("output/path.xyz"), getTargetConfiguration().getBinDirectory(
             RepositoryName.MAIN),
         ActionsTestUtil.NULL_ARTIFACT_OWNER);
     final Artifact outputIfso = getDerivedArtifact(
-        new PathFragment("output/path.ifso"), getTargetConfiguration().getBinDirectory(
+        PathFragment.create("output/path.ifso"), getTargetConfiguration().getBinDirectory(
             RepositoryName.MAIN),
         ActionsTestUtil.NULL_ARTIFACT_OWNER);
     CppLinkActionBuilder builder =
@@ -432,7 +432,7 @@
         new CppLinkActionBuilder(
                 ruleContext,
                 new Artifact(
-                    new PathFragment(outputPath),
+                    PathFragment.create(outputPath),
                     getTargetConfiguration()
                         .getBinDirectory(ruleContext.getRule().getRepository())),
                 ruleContext.getConfiguration(),
@@ -451,7 +451,7 @@
   }
 
   private CppLinkActionBuilder createLinkBuilder(Link.LinkTargetType type) throws Exception {
-    PathFragment output = new PathFragment("dummyRuleContext/output/path.a");
+    PathFragment output = PathFragment.create("dummyRuleContext/output/path.a");
     return createLinkBuilder(
         type,
         output.getPathString(),
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 f6ec5bc..07ba4ff 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
@@ -43,17 +43,17 @@
   @Test
   public void testDifferentOrderSameActionKey() throws Exception {
     Root root = Root.asDerivedRoot(rootDirectory, rootDirectory.getRelative("out"));
-    Artifact a = new Artifact(new PathFragment("a"), root);
-    Artifact b = new Artifact(new PathFragment("b"), root);
-    Artifact c = new Artifact(new PathFragment("c"), root);
-    Artifact d = new Artifact(new PathFragment("d"), root);
+    Artifact a = new Artifact(PathFragment.create("a"), root);
+    Artifact b = new Artifact(PathFragment.create("b"), root);
+    Artifact c = new Artifact(PathFragment.create("c"), root);
+    Artifact d = new Artifact(PathFragment.create("d"), root);
     CreateIncSymlinkAction action1 = new CreateIncSymlinkAction(NULL_ACTION_OWNER,
         ImmutableMap.of(a, b, c, d), root.getPath());
     // Can't reuse the artifacts here; that would lead to DuplicateArtifactException.
-    a = new Artifact(new PathFragment("a"), root);
-    b = new Artifact(new PathFragment("b"), root);
-    c = new Artifact(new PathFragment("c"), root);
-    d = new Artifact(new PathFragment("d"), root);
+    a = new Artifact(PathFragment.create("a"), root);
+    b = new Artifact(PathFragment.create("b"), root);
+    c = new Artifact(PathFragment.create("c"), root);
+    d = new Artifact(PathFragment.create("d"), root);
     CreateIncSymlinkAction action2 = new CreateIncSymlinkAction(NULL_ACTION_OWNER,
         ImmutableMap.of(c, d, a, b), root.getPath());
     assertEquals(action1.computeKey(), action2.computeKey());
@@ -62,13 +62,13 @@
   @Test
   public void testDifferentTargetsDifferentActionKey() throws Exception {
     Root root = Root.asDerivedRoot(rootDirectory, rootDirectory.getRelative("out"));
-    Artifact a = new Artifact(new PathFragment("a"), root);
-    Artifact b = new Artifact(new PathFragment("b"), root);
+    Artifact a = new Artifact(PathFragment.create("a"), root);
+    Artifact b = new Artifact(PathFragment.create("b"), root);
     CreateIncSymlinkAction action1 = new CreateIncSymlinkAction(NULL_ACTION_OWNER,
         ImmutableMap.of(a, b), root.getPath());
     // Can't reuse the artifacts here; that would lead to DuplicateArtifactException.
-    a = new Artifact(new PathFragment("a"), root);
-    b = new Artifact(new PathFragment("c"), root);
+    a = new Artifact(PathFragment.create("a"), root);
+    b = new Artifact(PathFragment.create("c"), root);
     CreateIncSymlinkAction action2 = new CreateIncSymlinkAction(NULL_ACTION_OWNER,
         ImmutableMap.of(a, b), root.getPath());
     assertThat(action2.computeKey()).isNotEqualTo(action1.computeKey());
@@ -77,13 +77,13 @@
   @Test
   public void testDifferentSymlinksDifferentActionKey() throws Exception {
     Root root = Root.asDerivedRoot(rootDirectory, rootDirectory.getRelative("out"));
-    Artifact a = new Artifact(new PathFragment("a"), root);
-    Artifact b = new Artifact(new PathFragment("b"), root);
+    Artifact a = new Artifact(PathFragment.create("a"), root);
+    Artifact b = new Artifact(PathFragment.create("b"), root);
     CreateIncSymlinkAction action1 = new CreateIncSymlinkAction(NULL_ACTION_OWNER,
         ImmutableMap.of(a, b), root.getPath());
     // Can't reuse the artifacts here; that would lead to DuplicateArtifactException.
-    a = new Artifact(new PathFragment("c"), root);
-    b = new Artifact(new PathFragment("b"), root);
+    a = new Artifact(PathFragment.create("c"), root);
+    b = new Artifact(PathFragment.create("b"), root);
     CreateIncSymlinkAction action2 = new CreateIncSymlinkAction(NULL_ACTION_OWNER,
         ImmutableMap.of(a, b), root.getPath());
     assertThat(action2.computeKey()).isNotEqualTo(action1.computeKey());
@@ -96,7 +96,7 @@
     Root root = Root.asDerivedRoot(rootDirectory, outputDir);
     Path symlink = rootDirectory.getRelative("out/a");
     Artifact a = new Artifact(symlink, root);
-    Artifact b = new Artifact(new PathFragment("b"), root);
+    Artifact b = new Artifact(PathFragment.create("b"), root);
     CreateIncSymlinkAction action = new CreateIncSymlinkAction(NULL_ACTION_OWNER,
         ImmutableMap.of(a, b), outputDir);
     action.execute(null);
@@ -113,7 +113,7 @@
     Root root = Root.asDerivedRoot(rootDirectory, outputDir);
     Path symlink = rootDirectory.getRelative("out/subdir/a");
     Artifact a = new Artifact(symlink, root);
-    Artifact b = new Artifact(new PathFragment("b"), root);
+    Artifact b = new Artifact(PathFragment.create("b"), root);
     CreateIncSymlinkAction action =
         new CreateIncSymlinkAction(NULL_ACTION_OWNER, ImmutableMap.of(a, b), outputDir);
     Path extra = rootDirectory.getRelative("out/extra");
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoaderTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoaderTest.java
index 1fd7a01..30b5af1 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoaderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoaderTest.java
@@ -540,7 +540,7 @@
             CompilationMode.FASTBUILD,
             LipoMode.OFF,
             LinkingMode.FULLY_STATIC,
-            new PathFragment("hello-world/ld")));
+            PathFragment.create("hello-world/ld")));
     assertEquals(
         Arrays.asList(
             "linker-flag-A-1",
@@ -551,7 +551,7 @@
             CompilationMode.DBG,
             LipoMode.OFF,
             LinkingMode.DYNAMIC,
-            new PathFragment("hello-world/ld")));
+            PathFragment.create("hello-world/ld")));
     assertEquals(
         Arrays.asList(
             "linker-flag-A-1",
@@ -562,7 +562,7 @@
             CompilationMode.OPT,
             LipoMode.OFF,
             LinkingMode.FULLY_STATIC,
-            new PathFragment("hello-world/ld")));
+            PathFragment.create("hello-world/ld")));
 
     assertEquals(
         Arrays.asList(
@@ -574,7 +574,7 @@
             CompilationMode.OPT,
             LipoMode.BINARY,
             LinkingMode.FULLY_STATIC,
-            new PathFragment("hello-world/ld")));
+            PathFragment.create("hello-world/ld")));
 
     assertEquals(
         Arrays.asList("objcopy-embed-flag-A-1", "objcopy-embed-flag-A-2"),
@@ -597,7 +597,7 @@
         Arrays.asList(
             getToolPath("/system-include-dir-A-1"), getToolPath("/system-include-dir-A-2")),
         toolchainA.getBuiltInIncludeDirectories());
-    assertEquals(new PathFragment("some"), toolchainA.getSysroot());
+    assertEquals(PathFragment.create("some"), toolchainA.getSysroot());
 
     // Cursory testing of the "B" toolchain only; assume that if none of
     // toolchain B bled through into toolchain A, the reverse also didn't occur. And
@@ -636,21 +636,21 @@
             CompilationMode.FASTBUILD,
             LipoMode.OFF,
             LinkingMode.FULLY_STATIC,
-            new PathFragment("hello-world/ld")));
+            PathFragment.create("hello-world/ld")));
     assertEquals(
         Collections.EMPTY_LIST,
         toolchainC.configureLinkerOptions(
             CompilationMode.DBG,
             LipoMode.OFF,
             LinkingMode.DYNAMIC,
-            new PathFragment("hello-world/ld")));
+            PathFragment.create("hello-world/ld")));
     assertEquals(
         Collections.EMPTY_LIST,
         toolchainC.configureLinkerOptions(
             CompilationMode.OPT,
             LipoMode.OFF,
             LinkingMode.FULLY_STATIC,
-            new PathFragment("hello-world/ld")));
+            PathFragment.create("hello-world/ld")));
     assertThat(toolchainC.getObjCopyOptionsForEmbedding()).isEmpty();
     assertThat(toolchainC.getLdOptionsForEmbedding()).isEmpty();
 
@@ -669,8 +669,9 @@
     PackageIdentifier packageIdentifier =
         PackageIdentifier.create(
             TestConstants.TOOLS_REPOSITORY,
-            new PathFragment(
-                new PathFragment(TestConstants.TOOLS_REPOSITORY_PATH), new PathFragment(path)));
+            PathFragment.create(
+                PathFragment.create(TestConstants.TOOLS_REPOSITORY_PATH),
+                PathFragment.create(path)));
     return packageIdentifier.getPathUnderExecRoot();
   }
 
@@ -690,7 +691,7 @@
             CompilationMode.DBG,
             lipoMode,
             LinkingMode.DYNAMIC,
-            new PathFragment("hello-world/ld")));
+            PathFragment.create("hello-world/ld")));
     assertEquals(
         ImmutableList.<String>of(
             "compiler-flag-B-1",
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/LTOBackendActionTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/LTOBackendActionTest.java
index eb196ec..70284d8 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/LTOBackendActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/LTOBackendActionTest.java
@@ -163,10 +163,10 @@
 
             if ((i & 8) == 0) {
               builder.addRunfilesSupplier(
-                  new RunfilesSupplierImpl(new PathFragment("a"), Runfiles.EMPTY, artifactA));
+                  new RunfilesSupplierImpl(PathFragment.create("a"), Runfiles.EMPTY, artifactA));
             } else {
               builder.addRunfilesSupplier(
-                  new RunfilesSupplierImpl(new PathFragment("a"), Runfiles.EMPTY, artifactB));
+                  new RunfilesSupplierImpl(PathFragment.create("a"), Runfiles.EMPTY, artifactB));
             }
 
             if ((i & 16) == 0) {
diff --git a/src/test/java/com/google/devtools/build/lib/rules/java/JavaUtilTest.java b/src/test/java/com/google/devtools/build/lib/rules/java/JavaUtilTest.java
index df3b4d5..7992575 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/java/JavaUtilTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/java/JavaUtilTest.java
@@ -29,13 +29,14 @@
 public class JavaUtilTest {
 
   private String getRootPath(String path) {
-    return JavaUtil.getJavaRoot(new PathFragment(path)).getPathString();
+    return JavaUtil.getJavaRoot(PathFragment.create(path)).getPathString();
   }
 
   @Test
   public void testGetJavaRoot() {
     assertThat(
-        JavaUtil.getJavaRoot(new PathFragment("path/without/Java/or/Javatests/or/Src/lowercase")))
+        JavaUtil.getJavaRoot(
+            PathFragment.create("path/without/Java/or/Javatests/or/Src/lowercase")))
         .isNull();
     assertThat(getRootPath("java/com/google/common/case")).isEqualTo("java");
     assertThat(getRootPath("javatests/com/google/common/case")).isEqualTo("javatests");
@@ -103,26 +104,26 @@
 
   @Test
   public void testGetJavaPackageName() {
-    assertThat(JavaUtil.getJavaPackageName(new PathFragment("java/com/google/foo/FooModule.java")))
-        .isEqualTo("com.google.foo");
-    assertThat(JavaUtil.getJavaPackageName(new PathFragment("org/foo/FooUtil.java")))
+    assertThat(JavaUtil.getJavaPackageName(
+        PathFragment.create("java/com/google/foo/FooModule.java"))).isEqualTo("com.google.foo");
+    assertThat(JavaUtil.getJavaPackageName(PathFragment.create("org/foo/FooUtil.java")))
         .isEqualTo("org.foo");
   }
 
   @Test
   public void testGetJavaFullClassname() {
     assertThat(
-        JavaUtil.getJavaFullClassname(new PathFragment("java/com/google/foo/FooModule.java")))
+        JavaUtil.getJavaFullClassname(PathFragment.create("java/com/google/foo/FooModule.java")))
         .isEqualTo("com.google.foo.FooModule.java");
-    assertThat(JavaUtil.getJavaFullClassname(new PathFragment("org/foo/FooUtil.java"))).isNull();
+    assertThat(JavaUtil.getJavaFullClassname(PathFragment.create("org/foo/FooUtil.java"))).isNull();
   }
 
   @Test
   public void testGetJavaPath() {
     assertThat(
         JavaUtil.getJavaPath(
-            new PathFragment("java/com/google/foo/FooModule.java")).getPathString())
+            PathFragment.create("java/com/google/foo/FooModule.java")).getPathString())
         .isEqualTo("com/google/foo/FooModule.java");
-    assertThat(JavaUtil.getJavaPath(new PathFragment("org/foo/FooUtil.java"))).isNull();
+    assertThat(JavaUtil.getJavaPath(PathFragment.create("org/foo/FooUtil.java"))).isNull();
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java
index 629a418..c9e1afa 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java
@@ -79,7 +79,7 @@
         "    name = 'w',",
         "    path = '/a/b/c',",
         ")");
-    assertEquals(new PathFragment("/a/b/c"),
+    assertEquals(PathFragment.create("/a/b/c"),
         TestingRepositoryFunction.getTargetPath(rule, rootDirectory));
   }
 
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 ef48219..a8ecc55 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
@@ -58,7 +58,7 @@
 public class ExperimentalStateTrackerTest extends FoundationTestCase {
 
   private Action mockAction(String progressMessage, String primaryOutput) {
-    Path path = outputBase.getRelative(new PathFragment(primaryOutput));
+    Path path = outputBase.getRelative(PathFragment.create(primaryOutput));
     Artifact artifact = new Artifact(path, Root.asSourceRoot(path));
 
     Action action = Mockito.mock(Action.class);
@@ -424,7 +424,7 @@
     String primaryOutput = "some/path/to/a/file";
 
     ManualClock clock = new ManualClock();
-    Path path = outputBase.getRelative(new PathFragment(primaryOutput));
+    Path path = outputBase.getRelative(PathFragment.create(primaryOutput));
     Artifact artifact = new Artifact(path, Root.asSourceRoot(path));
     ActionExecutionMetadata actionMetadata = Mockito.mock(ActionExecutionMetadata.class);
     when(actionMetadata.getOwner()).thenReturn(Mockito.mock(ActionOwner.class));
diff --git a/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTest.java b/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTest.java
index 3db7b36..4fac68d 100644
--- a/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTest.java
+++ b/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTest.java
@@ -42,7 +42,7 @@
 
   @Test
   public void testParseManifestFile() throws Exception {
-    PathFragment targetDir = new PathFragment("runfiles");
+    PathFragment targetDir = PathFragment.create("runfiles");
 
     Path testFile = workspaceDir.getRelative("testfile");
     FileSystemUtils.createEmptyFile(testFile);
@@ -58,15 +58,15 @@
         fileSystem, mounts, targetDir, manifestFile.getPathFile(), false, "");
 
     Map<PathFragment, Path> expected = new HashMap<>();
-    expected.put(new PathFragment("runfiles/x/testfile"), testFile);
-    expected.put(new PathFragment("runfiles/x/emptyfile"), null);
+    expected.put(PathFragment.create("runfiles/x/testfile"), testFile);
+    expected.put(PathFragment.create("runfiles/x/emptyfile"), null);
 
     assertThat(mounts).isEqualTo(expected);
   }
 
   @Test
   public void testParseFilesetManifestFile() throws Exception {
-    PathFragment targetDir = new PathFragment("fileset");
+    PathFragment targetDir = PathFragment.create("fileset");
 
     Path testFile = workspaceDir.getRelative("testfile");
     FileSystemUtils.createEmptyFile(testFile);
@@ -81,6 +81,7 @@
     SpawnHelpers.parseManifestFile(
         fileSystem, mounts, targetDir, manifestFile.getPathFile(), true, "workspace");
 
-    assertThat(mounts).isEqualTo(ImmutableMap.of(new PathFragment("fileset/x/testfile"), testFile));
+    assertThat(mounts).isEqualTo(
+        ImmutableMap.of(PathFragment.create("fileset/x/testfile"), testFile));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/sandbox/SymlinkedExecRootTest.java b/src/test/java/com/google/devtools/build/lib/sandbox/SymlinkedExecRootTest.java
index 24d1ca1..4ad8407 100644
--- a/src/test/java/com/google/devtools/build/lib/sandbox/SymlinkedExecRootTest.java
+++ b/src/test/java/com/google/devtools/build/lib/sandbox/SymlinkedExecRootTest.java
@@ -52,8 +52,8 @@
 
     SymlinkedExecRoot symlinkedExecRoot = new SymlinkedExecRoot(execRoot);
     symlinkedExecRoot.createFileSystem(
-        ImmutableMap.of(new PathFragment("such/input.txt"), helloTxt),
-        ImmutableSet.of(new PathFragment("very/output.txt")),
+        ImmutableMap.of(PathFragment.create("such/input.txt"), helloTxt),
+        ImmutableSet.of(PathFragment.create("very/output.txt")),
         ImmutableSet.of(execRoot.getRelative("wow/writable")));
 
     assertThat(execRoot.getRelative("such/input.txt").isSymbolicLink()).isTrue();
@@ -69,8 +69,8 @@
 
     SymlinkedExecRoot symlinkedExecRoot = new SymlinkedExecRoot(execRoot);
     symlinkedExecRoot.createFileSystem(
-        ImmutableMap.of(new PathFragment("such/input.txt"), helloTxt),
-        ImmutableSet.of(new PathFragment("very/output.txt")),
+        ImmutableMap.of(PathFragment.create("such/input.txt"), helloTxt),
+        ImmutableSet.of(PathFragment.create("very/output.txt")),
         ImmutableSet.of(execRoot.getRelative("wow/writable")));
 
     // Pretend to do some work inside the execRoot.
@@ -80,8 +80,8 @@
 
     // Reuse the same execRoot.
     symlinkedExecRoot.createFileSystem(
-        ImmutableMap.of(new PathFragment("such/input.txt"), helloTxt),
-        ImmutableSet.of(new PathFragment("very/output.txt")),
+        ImmutableMap.of(PathFragment.create("such/input.txt"), helloTxt),
+        ImmutableSet.of(PathFragment.create("very/output.txt")),
         ImmutableSet.of(execRoot.getRelative("wow/writable")));
 
     assertThat(execRoot.getRelative("such/input.txt").exists()).isTrue();
@@ -108,8 +108,8 @@
         ImmutableSet.<Path>of());
 
     FileSystemUtils.createEmptyFile(outputFile);
-    outputLink.createSymbolicLink(new PathFragment("output.txt"));
-    outputDangling.createSymbolicLink(new PathFragment("doesnotexist"));
+    outputLink.createSymbolicLink(PathFragment.create("output.txt"));
+    outputDangling.createSymbolicLink(PathFragment.create("doesnotexist"));
     outputDir.createDirectory();
     FileSystemUtils.createEmptyFile(outputDir.getRelative("test.txt"));
 
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 d24647a..954a3d5 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
@@ -121,12 +121,12 @@
     OutputPathMapper mapper = new OutputPathMapper() {
       @Override
       public PathFragment parentRelativeOutputPath(TreeFileArtifact inputTreeFileArtifact) {
-        return new PathFragment("conflict_path");
+        return PathFragment.create("conflict_path");
       }
     };
     SpawnActionTemplate spawnActionTemplate =
         new SpawnActionTemplate.Builder(inputTreeArtifact, outputTreeArtifact)
-            .setExecutable(new PathFragment("/bin/cp"))
+            .setExecutable(PathFragment.create("/bin/cp"))
             .setCommandLineTemplate(CustomCommandLine.builder().build())
             .setOutputPathMapper(mapper)
             .build(ActionsTestUtil.NULL_ACTION_OWNER);
@@ -152,10 +152,10 @@
         PathFragment path;
         switch (i) {
           case 0:
-            path = new PathFragment("path_prefix");
+            path = PathFragment.create("path_prefix");
             break;
           case 1:
-            path = new PathFragment("path_prefix/conflict");
+            path = PathFragment.create("path_prefix/conflict");
             break;
           default:
             path = inputTreeFileArtifact.getParentRelativePath();
@@ -167,7 +167,7 @@
     };
     SpawnActionTemplate spawnActionTemplate =
         new SpawnActionTemplate.Builder(inputTreeArtifact, outputTreeArtifact)
-            .setExecutable(new PathFragment("/bin/cp"))
+            .setExecutable(PathFragment.create("/bin/cp"))
             .setCommandLineTemplate(CustomCommandLine.builder().build())
             .setOutputPathMapper(mapper)
             .build(ActionsTestUtil.NULL_ACTION_OWNER);
@@ -199,7 +199,7 @@
   }
 
   private Artifact createTreeArtifact(String path) {
-    PathFragment execPath = new PathFragment("out").getRelative(path);
+    PathFragment execPath = PathFragment.create("out").getRelative(path);
     Path fullPath = rootDirectory.getRelative(execPath);
     return new SpecialArtifact(
         fullPath,
@@ -216,7 +216,7 @@
 
     for (String childRelativePath : childRelativePaths) {
       TreeFileArtifact treeFileArtifact = ActionInputHelper.treeFileArtifact(
-          treeArtifact, new PathFragment(childRelativePath));
+          treeArtifact, PathFragment.create(childRelativePath));
       scratch.file(treeFileArtifact.getPath().toString(), childRelativePath);
       // We do not care about the FileArtifactValues in this test.
       treeFileArtifactMap.put(treeFileArtifact, FileArtifactValue.create(treeFileArtifact));
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 c729fc6..21afd0a 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
@@ -389,11 +389,11 @@
   }
 
   private Artifact createSourceArtifact(String path) {
-    return new Artifact(new PathFragment(path), Root.asSourceRoot(root));
+    return new Artifact(PathFragment.create(path), Root.asSourceRoot(root));
   }
 
   private Artifact createDerivedArtifact(String path) {
-    PathFragment execPath = new PathFragment("out").getRelative(path);
+    PathFragment execPath = PathFragment.create("out").getRelative(path);
     Path fullPath = root.getRelative(execPath);
     Artifact output =
         new Artifact(
@@ -416,7 +416,7 @@
   }
 
   private Artifact createDerivedTreeArtifactOnly(String path) {
-    PathFragment execPath = new PathFragment("out").getRelative(path);
+    PathFragment execPath = PathFragment.create("out").getRelative(path);
     Path fullPath = root.getRelative(execPath);
     return new SpecialArtifact(
         fullPath,
@@ -429,7 +429,7 @@
   private TreeFileArtifact createFakeTreeFileArtifact(Artifact treeArtifact,
       String parentRelativePath, String content) throws Exception {
     TreeFileArtifact treeFileArtifact = ActionInputHelper.treeFileArtifact(
-        treeArtifact, new PathFragment(parentRelativePath));
+        treeArtifact, PathFragment.create(parentRelativePath));
     Path path = treeFileArtifact.getPath();
     FileSystemUtils.createDirectoryAndParents(path.getParentDirectory());
     writeFile(path, content);
@@ -499,9 +499,9 @@
       try {
         if (output.isTreeArtifact()) {
           TreeFileArtifact treeFileArtifact1 = ActionInputHelper.treeFileArtifact(
-              output, new PathFragment("child1"));
+              output, PathFragment.create("child1"));
           TreeFileArtifact treeFileArtifact2 = ActionInputHelper.treeFileArtifact(
-              output, new PathFragment("child2"));
+              output, PathFragment.create("child2"));
           TreeArtifactValue treeArtifactValue = TreeArtifactValue.create(ImmutableMap.of(
               treeFileArtifact1, FileArtifactValue.create(treeFileArtifact1),
               treeFileArtifact2, FileArtifactValue.create(treeFileArtifact2)));
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/DiffAwarenessManagerTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/DiffAwarenessManagerTest.java
index e2aebba..2a6f85e 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/DiffAwarenessManagerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/DiffAwarenessManagerTest.java
@@ -94,9 +94,9 @@
   @Test
   public void testHandlesUnprocessedDiffs() throws Exception {
     Path pathEntry = root.getRelative("pathEntry");
-    ModifiedFileSet diff1 = ModifiedFileSet.builder().modify(new PathFragment("file1")).build();
-    ModifiedFileSet diff2 = ModifiedFileSet.builder().modify(new PathFragment("file2")).build();
-    ModifiedFileSet diff3 = ModifiedFileSet.builder().modify(new PathFragment("file3")).build();
+    ModifiedFileSet diff1 = ModifiedFileSet.builder().modify(PathFragment.create("file1")).build();
+    ModifiedFileSet diff2 = ModifiedFileSet.builder().modify(PathFragment.create("file2")).build();
+    ModifiedFileSet diff3 = ModifiedFileSet.builder().modify(PathFragment.create("file3")).build();
     DiffAwarenessStub diffAwareness =
         new DiffAwarenessStub(ImmutableList.of(diff1, diff2, diff3, DiffAwarenessStub.BROKEN_DIFF));
     DiffAwarenessFactoryStub factory = new DiffAwarenessFactoryStub();
@@ -134,12 +134,12 @@
         new DiffAwarenessStub(ImmutableList.<ModifiedFileSet>of(), 1);
     factory1.inject(pathEntry, diffAwareness1);
     DiffAwarenessFactoryStub factory2 = new DiffAwarenessFactoryStub();
-    ModifiedFileSet diff2 = ModifiedFileSet.builder().modify(new PathFragment("file2")).build();
+    ModifiedFileSet diff2 = ModifiedFileSet.builder().modify(PathFragment.create("file2")).build();
     DiffAwarenessStub diffAwareness2 =
         new DiffAwarenessStub(ImmutableList.of(diff2, DiffAwarenessStub.BROKEN_DIFF));
     factory2.inject(pathEntry, diffAwareness2);
     DiffAwarenessFactoryStub factory3 = new DiffAwarenessFactoryStub();
-    ModifiedFileSet diff3 = ModifiedFileSet.builder().modify(new PathFragment("file3")).build();
+    ModifiedFileSet diff3 = ModifiedFileSet.builder().modify(PathFragment.create("file3")).build();
     DiffAwarenessStub diffAwareness3 = new DiffAwarenessStub(ImmutableList.of(diff3));
     factory3.inject(pathEntry, diffAwareness3);
     DiffAwarenessManager manager =
@@ -217,7 +217,7 @@
   private static class DiffAwarenessStub implements DiffAwareness {
 
     public static final ModifiedFileSet BROKEN_DIFF =
-        ModifiedFileSet.builder().modify(new PathFragment("special broken marker")).build();
+        ModifiedFileSet.builder().modify(PathFragment.create("special broken marker")).build();
 
     private boolean closed = false;
     private int curSequenceNum = 0;
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java
index 5eb13b3..68f0386 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java
@@ -303,7 +303,7 @@
             rootedPath("a"),
             rootedPath(""),
             RootedPath.toRootedPath(fs.getRootDirectory(), PathFragment.EMPTY_FRAGMENT),
-            RootedPath.toRootedPath(fs.getRootDirectory(), new PathFragment("outside")));
+            RootedPath.toRootedPath(fs.getRootDirectory(), PathFragment.create("outside")));
   }
 
   @Test
@@ -320,7 +320,7 @@
             rootedPath("a"),
             rootedPath(""),
             RootedPath.toRootedPath(fs.getRootDirectory(), PathFragment.EMPTY_FRAGMENT),
-            RootedPath.toRootedPath(fs.getRootDirectory(), new PathFragment("absolute")));
+            RootedPath.toRootedPath(fs.getRootDirectory(), PathFragment.create("absolute")));
   }
 
   @Test
@@ -341,10 +341,10 @@
             rootedPath("a"),
             rootedPath(""),
             RootedPath.toRootedPath(root, PathFragment.EMPTY_FRAGMENT),
-            RootedPath.toRootedPath(root, new PathFragment("output_base")),
-            RootedPath.toRootedPath(root, new PathFragment("output_base/external")),
-            RootedPath.toRootedPath(root, new PathFragment("output_base/external/a")),
-            RootedPath.toRootedPath(root, new PathFragment("output_base/external/a/b")));
+            RootedPath.toRootedPath(root, PathFragment.create("output_base")),
+            RootedPath.toRootedPath(root, PathFragment.create("output_base/external")),
+            RootedPath.toRootedPath(root, PathFragment.create("output_base/external/a")),
+            RootedPath.toRootedPath(root, PathFragment.create("output_base/external/a/b")));
   }
 
   @Test
@@ -1584,12 +1584,12 @@
   private Path symlink(String link, String target) throws Exception {
     Path path = path(link);
     FileSystemUtils.createDirectoryAndParents(path.getParentDirectory());
-    path.createSymbolicLink(new PathFragment(target));
+    path.createSymbolicLink(PathFragment.create(target));
     return path;
   }
 
   private Path path(String rootRelativePath) {
-    return pkgRoot.getRelative(new PathFragment(rootRelativePath));
+    return pkgRoot.getRelative(PathFragment.create(rootRelativePath));
   }
 
   private RootedPath rootedPath(String pathString) {
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FileSymlinkCycleUniquenessFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FileSymlinkCycleUniquenessFunctionTest.java
index 49414a9..aadce0f3 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/FileSymlinkCycleUniquenessFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/FileSymlinkCycleUniquenessFunctionTest.java
@@ -30,9 +30,9 @@
   @Test
   public void testHashCodeAndEqualsContract() throws Exception {
     Path root = new InMemoryFileSystem().getRootDirectory().getRelative("root");
-    RootedPath p1 = RootedPath.toRootedPath(root, new PathFragment("p1"));
-    RootedPath p2 = RootedPath.toRootedPath(root, new PathFragment("p2"));
-    RootedPath p3 = RootedPath.toRootedPath(root, new PathFragment("p3"));
+    RootedPath p1 = RootedPath.toRootedPath(root, PathFragment.create("p1"));
+    RootedPath p2 = RootedPath.toRootedPath(root, PathFragment.create("p2"));
+    RootedPath p3 = RootedPath.toRootedPath(root, PathFragment.create("p3"));
     ImmutableList<RootedPath> cycleA1 = ImmutableList.of(p1);
     ImmutableList<RootedPath> cycleB1 = ImmutableList.of(p2);
     ImmutableList<RootedPath> cycleC1 = ImmutableList.of(p1, p2, p3);
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 40d6d4e..949f09b 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
@@ -121,7 +121,7 @@
   }
 
   private Artifact getSourceArtifact(String path) throws Exception {
-    return new Artifact(new PathFragment(path), Root.asSourceRoot(rootDirectory));
+    return new Artifact(PathFragment.create(path), Root.asSourceRoot(rootDirectory));
   }
 
   private Artifact createSourceArtifact(String path) throws Exception {
@@ -177,15 +177,15 @@
   }
 
   private static FilesetOutputSymlink symlink(String from, Artifact to) {
-    return new FilesetOutputSymlink(new PathFragment(from), to.getPath().asFragment());
+    return new FilesetOutputSymlink(PathFragment.create(from), to.getPath().asFragment());
   }
 
   private static FilesetOutputSymlink symlink(String from, String to) {
-    return new FilesetOutputSymlink(new PathFragment(from), new PathFragment(to));
+    return new FilesetOutputSymlink(PathFragment.create(from), PathFragment.create(to));
   }
 
   private static FilesetOutputSymlink symlink(String from, RootedPath to) {
-    return new FilesetOutputSymlink(new PathFragment(from), to.asPath().asFragment());
+    return new FilesetOutputSymlink(PathFragment.create(from), to.asPath().asFragment());
   }
 
   private void assertSymlinksInOrder(
@@ -215,7 +215,7 @@
         FilesetTraversalParamsFactory.fileTraversal(
             /*ownerLabel=*/ label("//foo"),
             /*fileToTraverse=*/ file,
-            /*destPath=*/ new PathFragment("output-name"),
+            PathFragment.create("output-name"),
             /*symlinkBehaviorMode=*/ SymlinkBehavior.COPY,
             /*pkgBoundaryMode=*/ DONT_CROSS);
     assertSymlinksInOrder(params, symlink("output-name", file));
@@ -224,13 +224,13 @@
   private void assertFileTraversalForFileSymlink(SymlinkBehavior symlinks) throws Exception {
     Artifact file = createSourceArtifact("foo/file.real");
     Artifact symlink = getSourceArtifact("foo/file.sym");
-    symlink.getPath().createSymbolicLink(new PathFragment("file.real"));
+    symlink.getPath().createSymbolicLink(PathFragment.create("file.real"));
 
     FilesetTraversalParams params =
         FilesetTraversalParamsFactory.fileTraversal(
             /*ownerLabel=*/ label("//foo"),
             /*fileToTraverse=*/ symlink,
-            /*destPath=*/ new PathFragment("output-name"),
+            PathFragment.create("output-name"),
             /*symlinkBehaviorMode=*/ symlinks,
             /*pkgBoundaryMode=*/ DONT_CROSS);
     switch (symlinks) {
@@ -265,7 +265,7 @@
         FilesetTraversalParamsFactory.fileTraversal(
             /*ownerLabel=*/ label("//foo"),
             /*fileToTraverse=*/ dir,
-            /*destPath=*/ new PathFragment("output-name"),
+            PathFragment.create("output-name"),
             /*symlinkBehaviorMode=*/ SymlinkBehavior.COPY,
             /*pkgBoundaryMode=*/ DONT_CROSS);
     assertSymlinksInOrder(
@@ -277,13 +277,13 @@
     Artifact symlink = getSourceArtifact("foo/dir_sym");
     createFile(childOf(dir, "file.a"), "hello");
     createFile(childOf(dir, "sub/file.b"), "world");
-    symlink.getPath().createSymbolicLink(new PathFragment("dir_real"));
+    symlink.getPath().createSymbolicLink(PathFragment.create("dir_real"));
 
     FilesetTraversalParams params =
         FilesetTraversalParamsFactory.fileTraversal(
             /*ownerLabel=*/ label("//foo"),
             /*fileToTraverse=*/ symlink,
-            /*destPath=*/ new PathFragment("output-name"),
+            PathFragment.create("output-name"),
             /*symlinkBehaviorMode=*/ symlinks,
             /*pkgBoundaryMode=*/ DONT_CROSS);
     switch (symlinks) {
@@ -316,7 +316,7 @@
     RootedPath buildFile = createFile(childOf(dir, "subpkg/BUILD"), "blah");
     RootedPath fileB = createFile(childOf(dir, "subpkg/file.b"), "blah");
     fileAsym.asPath().getParentDirectory().createDirectory();
-    fileAsym.asPath().createSymbolicLink(new PathFragment("../file.a"));
+    fileAsym.asPath().createSymbolicLink(PathFragment.create("../file.a"));
 
     FilesetOutputSymlink outA = symlink("output-name/file.a", childOf(dir, "file.a"));
     FilesetOutputSymlink outAsym = null;
@@ -337,7 +337,7 @@
         FilesetTraversalParamsFactory.recursiveTraversalOfDirectory(
             /*ownerLabel=*/ label("//foo"),
             /*directoryToTraverse=*/ dir,
-            /*destPath=*/ new PathFragment("output-name"),
+            PathFragment.create("output-name"),
             /*excludes=*/ null,
             /*symlinkBehaviorMode=*/ symlinks,
             /*pkgBoundaryMode=*/ pkgBoundaryMode);
@@ -399,8 +399,8 @@
     createFile(childOf(dir, "subpkg/BUILD"), "blah");
     createFile(childOf(dir, "subpkg/file.b"), "blah");
     fileAsym.asPath().getParentDirectory().createDirectory();
-    fileAsym.asPath().createSymbolicLink(new PathFragment("../file.a"));
-    symlink.getPath().createSymbolicLink(new PathFragment("dir_real"));
+    fileAsym.asPath().createSymbolicLink(PathFragment.create("../file.a"));
+    symlink.getPath().createSymbolicLink(PathFragment.create("dir_real"));
 
     FilesetOutputSymlink outA = symlink("output-name/file.a", childOf(symlink, "file.a"));
     FilesetOutputSymlink outASym = null;
@@ -423,7 +423,7 @@
         FilesetTraversalParamsFactory.recursiveTraversalOfDirectory(
             /*ownerLabel=*/ label("//foo"),
             /*directoryToTraverse=*/ symlink,
-            /*destPath=*/ new PathFragment("output-name"),
+            PathFragment.create("output-name"),
             /*excludes=*/ null,
             /*symlinkBehaviorMode=*/ symlinks,
             /*pkgBoundaryMode=*/ pkgBoundaryMode);
@@ -488,8 +488,8 @@
     RootedPath fileB = createFile(siblingOf(subpkgBuildFile, "file.b"), "blah");
 
     scratch.dir(fileAsym.asPath().getParentDirectory().getPathString());
-    fileAsym.asPath().createSymbolicLink(new PathFragment("../file.a"));
-    subpkgSymlink.getPath().createSymbolicLink(new PathFragment("subpkg"));
+    fileAsym.asPath().createSymbolicLink(PathFragment.create("../file.a"));
+    subpkgSymlink.getPath().createSymbolicLink(PathFragment.create("subpkg"));
 
     FilesetOutputSymlink outBuild = symlink("output-name/BUILD", buildFile);
     FilesetOutputSymlink outA = symlink("output-name/file.a", fileA);
@@ -514,7 +514,7 @@
         FilesetTraversalParamsFactory.recursiveTraversalOfPackage(
             /*ownerLabel=*/ label("//foo"),
             /*directoryToTraverse=*/ buildFile,
-            /*destPath=*/ new PathFragment("output-name"),
+            PathFragment.create("output-name"),
             /*excludes=*/ null,
             /*symlinkBehaviorMode=*/ symlinks,
             /*pkgBoundaryMode=*/ pkgBoundaryMode);
@@ -576,14 +576,14 @@
         FilesetTraversalParamsFactory.fileTraversal(
             /*ownerLabel=*/ label("//foo"),
             /*fileToTraverse=*/ path,
-            /*destPath=*/ new PathFragment("inner-out"),
+            PathFragment.create("inner-out"),
             /*symlinkBehaviorMode=*/ SymlinkBehavior.COPY,
             /*pkgBoundaryMode=*/ DONT_CROSS);
     FilesetTraversalParams outer =
         FilesetTraversalParamsFactory.nestedTraversal(
             /*ownerLabel=*/ label("//foo:bar"),
             /*nested=*/ inner,
-            /*destDir=*/ new PathFragment("outer-out"),
+            PathFragment.create("outer-out"),
             /*excludes=*/ null);
     assertSymlinksInOrder(outer, symlink("outer-out/inner-out", rootedPath(path)));
   }
@@ -598,7 +598,7 @@
         FilesetTraversalParamsFactory.recursiveTraversalOfDirectory(
             /*ownerLabel=*/ label("//foo"),
             /*directoryToTraverse=*/ dir,
-            /*destPath=*/ new PathFragment(useInnerDir ? "inner-dir" : ""),
+            PathFragment.create(useInnerDir ? "inner-dir" : ""),
             /*excludes=*/ null,
             /*symlinkBehaviorMode=*/ SymlinkBehavior.COPY,
             /*pkgBoundaryMode=*/ DONT_CROSS);
@@ -606,7 +606,7 @@
         FilesetTraversalParamsFactory.nestedTraversal(
             /*ownerLabel=*/ label("//foo"),
             /*nested=*/ inner,
-            /*destDir=*/ new PathFragment("outer-dir"),
+            PathFragment.create("outer-dir"),
             ImmutableSet.<String>of("file.a", "sub/file.c"));
 
     if (useInnerDir) {
@@ -639,14 +639,14 @@
   public void testFileTraversalForDanglingSymlink() throws Exception {
     Artifact linkName = getSourceArtifact("foo/dangling.sym");
     RootedPath linkTarget = createFile(siblingOf(linkName, "target.file"), "blah");
-    linkName.getPath().createSymbolicLink(new PathFragment("target.file"));
+    linkName.getPath().createSymbolicLink(PathFragment.create("target.file"));
     linkTarget.asPath().delete();
 
     FilesetTraversalParams params =
         FilesetTraversalParamsFactory.fileTraversal(
             /*ownerLabel=*/ label("//foo"),
             /*fileToTraverse=*/ linkName,
-            /*destPath=*/ new PathFragment("output-name"),
+            PathFragment.create("output-name"),
             /*symlinkBehaviorMode=*/ SymlinkBehavior.COPY,
             /*pkgBoundaryMode=*/ DONT_CROSS);
     assertSymlinksInOrder(params); // expect empty results
@@ -659,14 +659,14 @@
     Artifact linkName = getSourceArtifact("foo/file.sym");
     Artifact linkTarget = getSourceArtifact("foo/file.actual");
     createFile(linkTarget);
-    linkName.getPath().createSymbolicLink(new PathFragment("file.actual"));
+    linkName.getPath().createSymbolicLink(PathFragment.create("file.actual"));
 
     // Ensure the symlink and its target would be included if they weren't explicitly excluded.
     FilesetTraversalParams params =
         FilesetTraversalParamsFactory.recursiveTraversalOfPackage(
             /* ownerLabel */ label("//foo"),
             /* buildFile */ buildFile,
-            /* destPath */ new PathFragment("output-name"),
+            PathFragment.create("output-name"),
             /* excludes */ ImmutableSet.<String>of(),
             /* symlinkBehaviorMode */ symlinkBehavior,
             /* pkgBoundaryMode */ PackageBoundaryMode.DONT_CROSS);
@@ -686,7 +686,7 @@
         FilesetTraversalParamsFactory.recursiveTraversalOfPackage(
             /* ownerLabel */ label("//foo"),
             /* buildFile */ buildFile,
-            /* destPath */ new PathFragment("output-name"),
+            PathFragment.create("output-name"),
             /* excludes */ ImmutableSet.of("file.sym"),
             /* symlinkBehaviorMode */ symlinkBehavior,
             /* pkgBoundaryMode */ PackageBoundaryMode.DONT_CROSS);
@@ -710,7 +710,7 @@
         FilesetTraversalParamsFactory.fileTraversal(
             /*ownerLabel=*/ label("//foo"),
             /*fileToTraverse=*/ path,
-            /*destPath=*/ new PathFragment("output-name"),
+            PathFragment.create("output-name"),
             /*symlinkBehaviorMode=*/ SymlinkBehavior.COPY,
             /*pkgBoundaryMode=*/ DONT_CROSS);
     assertSymlinksInOrder(params); // expect empty results
@@ -720,14 +720,14 @@
   public void testRecursiveTraversalForDanglingSymlink() throws Exception {
     Artifact linkName = getSourceArtifact("foo/dangling.sym");
     RootedPath linkTarget = createFile(siblingOf(linkName, "target.file"), "blah");
-    linkName.getPath().createSymbolicLink(new PathFragment("target.file"));
+    linkName.getPath().createSymbolicLink(PathFragment.create("target.file"));
     linkTarget.asPath().delete();
 
     FilesetTraversalParams params =
         FilesetTraversalParamsFactory.recursiveTraversalOfDirectory(
             /*ownerLabel=*/ label("//foo"),
             /*directoryToTraverse=*/ linkName,
-            /*destPath=*/ new PathFragment("output-name"),
+            PathFragment.create("output-name"),
             /*excludes=*/ null,
             /*symlinkBehaviorMode=*/ SymlinkBehavior.COPY,
             /*pkgBoundaryMode=*/ DONT_CROSS);
@@ -742,7 +742,7 @@
         FilesetTraversalParamsFactory.recursiveTraversalOfDirectory(
             /*ownerLabel=*/ label("//foo"),
             /*directoryToTraverse=*/ path,
-            /*destPath=*/ new PathFragment("output-name"),
+            PathFragment.create("output-name"),
             /*excludes=*/ null,
             /*symlinkBehaviorMode=*/ SymlinkBehavior.COPY,
             /*pkgBoundaryMode=*/ DONT_CROSS);
@@ -853,7 +853,7 @@
         return FilesetTraversalParamsFactory.fileTraversal(
             label((String) kwArgs.get("ownerLabel")),
             getSourceArtifact((String) kwArgs.get("fileToTraverse")),
-            new PathFragment((String) kwArgs.get("destPath")),
+            PathFragment.create((String) kwArgs.get("destPath")),
             ((SymlinkBehavior) kwArgs.get("symlinkBehaviorMode")),
             (PackageBoundaryMode) kwArgs.get("pkgBoundaryMode"));
       }
@@ -881,7 +881,7 @@
         return FilesetTraversalParamsFactory.recursiveTraversalOfDirectory(
             label((String) kwArgs.get("ownerLabel")),
             getSourceArtifact((String) kwArgs.get("directoryToTraverse")),
-            new PathFragment((String) kwArgs.get("destPath")),
+            PathFragment.create((String) kwArgs.get("destPath")),
             (Set<String>) kwArgs.get("excludes"),
             ((SymlinkBehavior) kwArgs.get("symlinkBehaviorMode")),
             (PackageBoundaryMode) kwArgs.get("pkgBoundaryMode"));
@@ -910,7 +910,7 @@
         return FilesetTraversalParamsFactory.recursiveTraversalOfPackage(
             label((String) kwArgs.get("ownerLabel")),
             getSourceArtifact((String) kwArgs.get("buildFile")),
-            new PathFragment((String) kwArgs.get("destPath")),
+            PathFragment.create((String) kwArgs.get("destPath")),
             (Set<String>) kwArgs.get("excludes"),
             ((SymlinkBehavior) kwArgs.get("symlinkBehaviorMode")),
             (PackageBoundaryMode) kwArgs.get("pkgBoundaryMode"));
@@ -924,7 +924,7 @@
         FilesetTraversalParamsFactory.fileTraversal(
             /*ownerLabel=*/ label("//blah"),
             /*fileToTraverse=*/ getSourceArtifact("blah/file.a"),
-            /*destPath=*/ new PathFragment("output-name"),
+            PathFragment.create("output-name"),
             /*symlinkBehaviorMode=*/ SymlinkBehavior.COPY,
             /*pkgBoundaryMode=*/ DONT_CROSS);
 
@@ -932,7 +932,7 @@
         FilesetTraversalParamsFactory.fileTraversal(
             /*ownerLabel=*/ label("//blah"),
             /*fileToTraverse=*/ getSourceArtifact("meow/file.b"),
-            /*destPath=*/ new PathFragment("output-name"),
+            PathFragment.create("output-name"),
             /*symlinkBehaviorMode=*/ SymlinkBehavior.COPY,
             /*pkgBoundaryMode=*/ DONT_CROSS);
 
@@ -949,7 +949,7 @@
         return FilesetTraversalParamsFactory.nestedTraversal(
             label((String) kwArgs.get("ownerLabel")),
             (FilesetTraversalParams) kwArgs.get("nested"),
-            new PathFragment((String) kwArgs.get("destDir")),
+            PathFragment.create((String) kwArgs.get("destDir")),
             (Set<String>) kwArgs.get("excludes"));
       }
     }.doTest();
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 0dba1d9..2c92706 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
@@ -155,7 +155,7 @@
     assertEmptyDiff(getDirtyFilesystemKeys(evaluator, checker));
 
     SkyKey skyKey = FileStateValue.key(
-        RootedPath.toRootedPath(fs.getRootDirectory(), new PathFragment("foo")));
+        RootedPath.toRootedPath(fs.getRootDirectory(), PathFragment.create("foo")));
     EvaluationResult<SkyValue> result =
         driver.evaluate(
             ImmutableList.of(skyKey),
@@ -206,13 +206,13 @@
     FileSystemUtils.ensureSymbolicLink(sym1, path);
     FileSystemUtils.ensureSymbolicLink(sym2, path);
     SkyKey fooKey =
-        FileValue.key(RootedPath.toRootedPath(fs.getRootDirectory(), new PathFragment("foo")));
+        FileValue.key(RootedPath.toRootedPath(fs.getRootDirectory(), PathFragment.create("foo")));
     RootedPath symlinkRootedPath =
-        RootedPath.toRootedPath(fs.getRootDirectory(), new PathFragment("bar"));
+        RootedPath.toRootedPath(fs.getRootDirectory(), PathFragment.create("bar"));
     SkyKey symlinkKey = FileValue.key(symlinkRootedPath);
     SkyKey symlinkFileStateKey = FileStateValue.key(symlinkRootedPath);
     RootedPath sym1RootedPath =
-        RootedPath.toRootedPath(fs.getRootDirectory(), new PathFragment("sym1"));
+        RootedPath.toRootedPath(fs.getRootDirectory(), PathFragment.create("sym1"));
     SkyKey sym1FileStateKey = FileStateValue.key(sym1RootedPath);
     Iterable<SkyKey> allKeys = ImmutableList.of(symlinkKey, fooKey);
 
@@ -274,10 +274,10 @@
 
     SkyKey key1 =
         FileStateValue.key(
-            RootedPath.toRootedPath(fs.getRootDirectory(), new PathFragment("foo1")));
+            RootedPath.toRootedPath(fs.getRootDirectory(), PathFragment.create("foo1")));
     SkyKey key2 =
         FileStateValue.key(
-            RootedPath.toRootedPath(fs.getRootDirectory(), new PathFragment("foo2")));
+            RootedPath.toRootedPath(fs.getRootDirectory(), PathFragment.create("foo2")));
     Iterable<SkyKey> skyKeys = ImmutableList.of(key1, key2);
     EvaluationResult<SkyValue> result =
         driver.evaluate(
@@ -304,10 +304,11 @@
   public void testFileWithIOExceptionNotConsideredDirty() throws Exception {
     Path path = fs.getPath("/testroot/foo");
     path.getParentDirectory().createDirectory();
-    path.createSymbolicLink(new PathFragment("bar"));
+    path.createSymbolicLink(PathFragment.create("bar"));
 
     fs.readlinkThrowsIoException = true;
-    SkyKey fileKey = FileStateValue.key(RootedPath.toRootedPath(pkgRoot, new PathFragment("foo")));
+    SkyKey fileKey = FileStateValue.key(
+        RootedPath.toRootedPath(pkgRoot, PathFragment.create("foo")));
     EvaluationResult<SkyValue> result =
         driver.evaluate(
             ImmutableList.of(fileKey),
@@ -763,8 +764,8 @@
 
   @Test
   public void testPropagatesRuntimeExceptions() throws Exception {
-    Collection<SkyKey> values =
-        ImmutableList.of(FileValue.key(RootedPath.toRootedPath(pkgRoot, new PathFragment("foo"))));
+    Collection<SkyKey> values = ImmutableList.of(
+        FileValue.key(RootedPath.toRootedPath(pkgRoot, PathFragment.create("foo"))));
     driver.evaluate(
         values, false, SkyframeExecutor.DEFAULT_THREAD_COUNT, NullEventHandler.INSTANCE);
     FilesystemValueChecker checker = new FilesystemValueChecker(null, null);
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunctionTest.java
index 564e466..a2d5178 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunctionTest.java
@@ -143,7 +143,7 @@
     scratch.file("some/path/BUILD");
 
     LocalRepositoryLookupValue repositoryLookupValue =
-        lookupDirectory(RootedPath.toRootedPath(rootDirectory, new PathFragment("some/path")));
+        lookupDirectory(RootedPath.toRootedPath(rootDirectory, PathFragment.create("some/path")));
     assertThat(repositoryLookupValue).isNotNull();
     assertThat(repositoryLookupValue.getRepository()).isEqualTo(RepositoryName.MAIN);
   }
@@ -155,7 +155,7 @@
     scratch.file("local/repo/BUILD");
 
     LocalRepositoryLookupValue repositoryLookupValue =
-        lookupDirectory(RootedPath.toRootedPath(rootDirectory, new PathFragment("local/repo")));
+        lookupDirectory(RootedPath.toRootedPath(rootDirectory, PathFragment.create("local/repo")));
     assertThat(repositoryLookupValue).isNotNull();
     assertThat(repositoryLookupValue.getRepository().getName()).isEqualTo("@local");
   }
@@ -169,7 +169,7 @@
 
     LocalRepositoryLookupValue repositoryLookupValue =
         lookupDirectory(
-            RootedPath.toRootedPath(rootDirectory, new PathFragment("local/repo/sub/package")));
+            RootedPath.toRootedPath(rootDirectory, PathFragment.create("local/repo/sub/package")));
     assertThat(repositoryLookupValue).isNotNull();
     assertThat(repositoryLookupValue.getRepository().getName()).isEqualTo("@local");
   }
@@ -181,7 +181,7 @@
     scratch.file("local/repo/BUILD");
 
     LocalRepositoryLookupValue repositoryLookupValue =
-        lookupDirectory(RootedPath.toRootedPath(rootDirectory, new PathFragment("local/repo")));
+        lookupDirectory(RootedPath.toRootedPath(rootDirectory, PathFragment.create("local/repo")));
     assertThat(repositoryLookupValue).isNotNull();
     assertThat(repositoryLookupValue.getRepository()).isEqualTo(RepositoryName.MAIN);
   }
@@ -198,7 +198,7 @@
     scratch.file("local/repo/BUILD");
 
     SkyKey localRepositoryKey =
-        createKey(RootedPath.toRootedPath(rootDirectory, new PathFragment("local/repo")));
+        createKey(RootedPath.toRootedPath(rootDirectory, PathFragment.create("local/repo")));
     EvaluationResult<LocalRepositoryLookupValue> result = lookupDirectory(localRepositoryKey);
 
     assertThatEvaluationResult(result)
@@ -218,7 +218,7 @@
     scratch.file("local/repo/BUILD");
 
     LocalRepositoryLookupValue repositoryLookupValue =
-        lookupDirectory(RootedPath.toRootedPath(rootDirectory, new PathFragment("local/repo")));
+        lookupDirectory(RootedPath.toRootedPath(rootDirectory, PathFragment.create("local/repo")));
     assertThat(repositoryLookupValue).isNotNull();
     // In this case, the repository should be MAIN as we can't find any local_repository rules.
     assertThat(repositoryLookupValue.getRepository()).isEqualTo(RepositoryName.MAIN);
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java
index 98bedeb..758c41b 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java
@@ -124,7 +124,7 @@
 
     preparePackageLoading(rootDirectory);
 
-    SkyKey pkgLookupKey = PackageLookupValue.key(new PathFragment("foo"));
+    SkyKey pkgLookupKey = PackageLookupValue.key(PathFragment.create("foo"));
     EvaluationResult<PackageLookupValue> result = SkyframeExecutorTestUtils.evaluate(
         getSkyframeExecutor(), pkgLookupKey, /*keepGoing=*/false, reporter);
     assertFalse(result.hasError());
@@ -336,7 +336,7 @@
     scratch.overwriteFile("bar/a",
         "subinclude('//baz:c')");
     getSkyframeExecutor().invalidateFilesUnderPathForTesting(reporter,
-        ModifiedFileSet.builder().modify(new PathFragment("bar/a")).build(), rootDirectory);
+        ModifiedFileSet.builder().modify(PathFragment.create("bar/a")).build(), rootDirectory);
 
     value = validPackage(skyKey);
     assertThat(value.getPackage().getSubincludeLabels()).containsExactly(
@@ -368,7 +368,7 @@
     getSkyframeExecutor()
         .invalidateFilesUnderPathForTesting(
             reporter,
-            ModifiedFileSet.builder().modify(new PathFragment("foo/d.txt")).build(),
+            ModifiedFileSet.builder().modify(PathFragment.create("foo/d.txt")).build(),
             rootDirectory);
     value = validPackage(skyKey);
     assertThat(
@@ -399,7 +399,7 @@
     getSkyframeExecutor()
         .invalidateFilesUnderPathForTesting(
             reporter,
-            ModifiedFileSet.builder().modify(new PathFragment("foo/BUILD")).build(),
+            ModifiedFileSet.builder().modify(PathFragment.create("foo/BUILD")).build(),
             rootDirectory);
     assertSrcs(validPackage(skyKey), "foo", "//foo:a.config", "//foo:b.txt");
     scratch.overwriteFile(
@@ -407,7 +407,7 @@
     getSkyframeExecutor()
         .invalidateFilesUnderPathForTesting(
             reporter,
-            ModifiedFileSet.builder().modify(new PathFragment("foo/BUILD")).build(),
+            ModifiedFileSet.builder().modify(PathFragment.create("foo/BUILD")).build(),
             rootDirectory);
     assertSrcs(validPackage(skyKey), "foo", "//foo:a.config", "//foo:b.txt");
     getSkyframeExecutor().resetEvaluator();
@@ -461,7 +461,7 @@
     getSkyframeExecutor()
         .invalidateFilesUnderPathForTesting(
             reporter,
-            ModifiedFileSet.builder().modify(new PathFragment("foo/BUILD")).build(),
+            ModifiedFileSet.builder().modify(PathFragment.create("foo/BUILD")).build(),
             rootDirectory);
     PackageValue fooValue2 = validPackage(fooKey);
     assertThat(fooValue2).isNotEqualTo(fooValue);
@@ -503,7 +503,7 @@
     getSkyframeExecutor()
         .invalidateFilesUnderPathForTesting(
             reporter,
-            ModifiedFileSet.builder().modify(new PathFragment("foo/irrelevant")).build(),
+            ModifiedFileSet.builder().modify(PathFragment.create("foo/irrelevant")).build(),
             rootDirectory);
     assertThat(validPackage(skyKey)).isSameAs(value);
   }
@@ -521,7 +521,7 @@
     getSkyframeExecutor()
         .invalidateFilesUnderPathForTesting(
             reporter,
-            ModifiedFileSet.builder().modify(new PathFragment("foo/irrelevant")).build(),
+            ModifiedFileSet.builder().modify(PathFragment.create("foo/irrelevant")).build(),
             rootDirectory);
     assertThat(validPackage(skyKey)).isSameAs(value);
   }
@@ -574,8 +574,10 @@
     scratch.overwriteFile("bar/ext.bzl",
         "load('/qux/ext', 'c')",
         "a = c");
-    getSkyframeExecutor().invalidateFilesUnderPathForTesting(reporter,
-        ModifiedFileSet.builder().modify(new PathFragment("bar/ext.bzl")).build(), rootDirectory);
+    getSkyframeExecutor().invalidateFilesUnderPathForTesting(
+        reporter,
+        ModifiedFileSet.builder().modify(PathFragment.create("bar/ext.bzl")).build(),
+        rootDirectory);
 
     value = validPackage(skyKey);
     assertThat(value.getPackage().getSkylarkFileDependencies()).containsExactly(
@@ -655,7 +657,7 @@
   public void testSymlinkCycleWithSkylarkExtension() throws Exception {
     reporter.removeHandler(failFastHandler);
     Path extensionFilePath = scratch.resolve("/workspace/test/skylark/extension.bzl");
-    FileSystemUtils.ensureSymbolicLink(extensionFilePath, new PathFragment("extension.bzl"));
+    FileSystemUtils.ensureSymbolicLink(extensionFilePath, PathFragment.create("extension.bzl"));
     scratch.file("test/skylark/BUILD",
         "load('/test/skylark/extension', 'a')",
         "genrule(name = gr,",
@@ -715,7 +717,7 @@
                 com.google.devtools.build.lib.skyframe.FileStateValue.key(
                     RootedPath.toRootedPath(
                         workspacePath.getParentDirectory(),
-                        new PathFragment(workspacePath.getBaseName())))));
+                        PathFragment.create(workspacePath.getBaseName())))));
 
     reporter.removeHandler(failFastHandler);
     EvaluationResult<PackageValue> result =
@@ -751,7 +753,7 @@
         "#some-irrelevant-comment");
 
     getSkyframeExecutor().invalidateFilesUnderPathForTesting(reporter,
-        ModifiedFileSet.builder().modify(new PathFragment("foo/BUILD")).build(), rootDirectory);
+        ModifiedFileSet.builder().modify(PathFragment.create("foo/BUILD")).build(), rootDirectory);
 
     value = validPackage(skyKey);
     assertFalse(value.getPackage().containsErrors());
@@ -767,7 +769,7 @@
 
     scratch.file("foo/nope");
     getSkyframeExecutor().invalidateFilesUnderPathForTesting(reporter,
-        ModifiedFileSet.builder().modify(new PathFragment("foo/nope")).build(), rootDirectory);
+        ModifiedFileSet.builder().modify(PathFragment.create("foo/nope")).build(), rootDirectory);
 
     PackageValue newValue = validPackage(skyKey);
     assertFalse(newValue.getPackage().containsErrors());
@@ -803,7 +805,7 @@
         "[sh_library(name = x + '-matched') for x in glob(['**'], exclude_directories = 0)]",
         "#some-irrelevant-comment");
     getSkyframeExecutor().invalidateFilesUnderPathForTesting(reporter,
-        ModifiedFileSet.builder().modify(new PathFragment("foo/BUILD")).build(), rootDirectory);
+        ModifiedFileSet.builder().modify(PathFragment.create("foo/BUILD")).build(), rootDirectory);
 
     value = validPackage(skyKey);
     assertFalse(value.getPackage().containsErrors());
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java
index 0c4c1d4..6ad7725 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java
@@ -199,7 +199,7 @@
     scratch.file("blacklisted/subdir/BUILD");
     scratch.file("blacklisted/BUILD");
     PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE.set(differencer,
-        new PathFragment("config/blacklisted.txt"));
+        PathFragment.create("config/blacklisted.txt"));
     Path blacklist = scratch.file("config/blacklisted.txt", "blacklisted");
 
     ImmutableSet<String> pkgs = ImmutableSet.of("blacklisted/subdir", "blacklisted");
@@ -213,7 +213,7 @@
     scratch.overwriteFile("config/blacklisted.txt", "not_blacklisted");
     RootedPath rootedBlacklist = RootedPath.toRootedPath(
         blacklist.getParentDirectory().getParentDirectory(),
-        new PathFragment("config/blacklisted.txt"));
+        PathFragment.create("config/blacklisted.txt"));
     differencer.invalidate(ImmutableSet.of(FileStateValue.key(rootedBlacklist)));
     for (String pkg : pkgs) {
       PackageLookupValue packageLookupValue = lookupPackage(pkg);
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunctionSmartNegationTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunctionSmartNegationTest.java
index 50c3a2c..8786b42 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunctionSmartNegationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunctionSmartNegationTest.java
@@ -90,7 +90,7 @@
 
     // and a blacklist for the malformed package,
     getSkyframeExecutor().setBlacklistedPackagePrefixesFile(
-        new PathFragment("config/blacklist.txt"));
+        PathFragment.create("config/blacklist.txt"));
     scratch.file("config/blacklist.txt", "foo/foo");
 
     assertSkipsFoo(patternSequence);
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfTargetsUnderDirectoryFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfTargetsUnderDirectoryFunctionTest.java
index b790f86..1602f4a 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfTargetsUnderDirectoryFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfTargetsUnderDirectoryFunctionTest.java
@@ -97,7 +97,7 @@
     createPackages();
 
     // When package "a" is evaluated,
-    SkyKey key = createPrepDepsKey(rootDirectory, new PathFragment("a"));
+    SkyKey key = createPrepDepsKey(rootDirectory, PathFragment.create("a"));
     EvaluationResult<?> evaluationResult = getEvaluationResult(key);
     WalkableGraph graph = Preconditions.checkNotNull(evaluationResult.getWalkableGraph());
 
@@ -122,7 +122,7 @@
     createPackages();
 
     // When package "a" is evaluated under a test-only filtering policy,
-    SkyKey key = createPrepDepsKey(rootDirectory, new PathFragment("a"),
+    SkyKey key = createPrepDepsKey(rootDirectory, PathFragment.create("a"),
         ImmutableSet.<PathFragment>of(), FilteringPolicies.FILTER_TESTS);
     EvaluationResult<?> evaluationResult = getEvaluationResult(key);
     WalkableGraph graph = Preconditions.checkNotNull(evaluationResult.getWalkableGraph());
@@ -157,12 +157,12 @@
 
     // When the top package is evaluated via PrepareDepsOfTargetsUnderDirectoryValue with "a/b"
     // excluded,
-    PathFragment excludedPathFragment = new PathFragment("a/b");
-    SkyKey key = createPrepDepsKey(rootDirectory, new PathFragment("a"),
+    PathFragment excludedPathFragment = PathFragment.create("a/b");
+    SkyKey key = createPrepDepsKey(rootDirectory, PathFragment.create("a"),
         ImmutableSet.of(excludedPathFragment));
     SkyKey collectkey =
         createCollectPackagesKey(
-            rootDirectory, new PathFragment("a"), ImmutableSet.of(excludedPathFragment));
+            rootDirectory, PathFragment.create("a"), ImmutableSet.of(excludedPathFragment));
     EvaluationResult<?> evaluationResult = getEvaluationResult(key, collectkey);
     CollectPackagesUnderDirectoryValue value =
         (CollectPackagesUnderDirectoryValue)
@@ -171,7 +171,7 @@
                 .getValue(
                     createCollectPackagesKey(
                         rootDirectory,
-                        new PathFragment("a"),
+                        PathFragment.create("a"),
                         ImmutableSet.of(excludedPathFragment)));
 
     // Then the value reports that "a" is a package,
@@ -181,7 +181,7 @@
     RootedPath onlySubdir =
         Iterables.getOnlyElement(
             value.getSubdirectoryTransitivelyContainsPackagesOrErrors().keySet());
-    assertThat(onlySubdir.getRelativePath()).isEqualTo(new PathFragment("a/c"));
+    assertThat(onlySubdir.getRelativePath()).isEqualTo(PathFragment.create("a/c"));
 
     // And the "a/c" subdirectory reports a package under it.
     assertThat(value.getSubdirectoryTransitivelyContainsPackagesOrErrors().get(onlySubdir))
@@ -199,7 +199,7 @@
     assertTrue(
         exists(
             createPrepDepsKey(
-                rootDirectory, new PathFragment("a/c"), ImmutableSet.<PathFragment>of()),
+                rootDirectory, PathFragment.create("a/c"), ImmutableSet.<PathFragment>of()),
             graph));
   }
 
@@ -212,17 +212,18 @@
     scratch.file("a/b/d/helloworld");
 
     // When the top package is evaluated for recursive package values, and "a/b/c" is excluded,
-    ImmutableSet<PathFragment> excludedPaths = ImmutableSet.of(new PathFragment("a/b/c"));
-    SkyKey key = createPrepDepsKey(rootDirectory, new PathFragment("a"), excludedPaths);
+    ImmutableSet<PathFragment> excludedPaths = ImmutableSet.of(PathFragment.create("a/b/c"));
+    SkyKey key = createPrepDepsKey(rootDirectory, PathFragment.create("a"), excludedPaths);
     SkyKey collectKey =
-        createCollectPackagesKey(rootDirectory, new PathFragment("a"), excludedPaths);
+        createCollectPackagesKey(rootDirectory, PathFragment.create("a"), excludedPaths);
     EvaluationResult<?> evaluationResult = getEvaluationResult(key, collectKey);
     CollectPackagesUnderDirectoryValue value =
         (CollectPackagesUnderDirectoryValue)
             evaluationResult
                 .getWalkableGraph()
                 .getValue(
-                    createCollectPackagesKey(rootDirectory, new PathFragment("a"), excludedPaths));
+                    createCollectPackagesKey(
+                        rootDirectory, PathFragment.create("a"), excludedPaths));
 
     // Then the value reports that "a" is a package,
     assertThat(value.isDirectoryPackage()).isTrue();
@@ -231,7 +232,7 @@
     RootedPath onlySubdir =
         Iterables.getOnlyElement(
             value.getSubdirectoryTransitivelyContainsPackagesOrErrors().keySet());
-    assertThat(onlySubdir.getRelativePath()).isEqualTo(new PathFragment("a/b"));
+    assertThat(onlySubdir.getRelativePath()).isEqualTo(PathFragment.create("a/b"));
 
     // And the "a/b" subdirectory does not report a package under it (because it got excluded).
     assertThat(value.getSubdirectoryTransitivelyContainsPackagesOrErrors().get(onlySubdir))
@@ -240,7 +241,8 @@
     // Also, the computation graph contains a cached value for "a/b" with "a/b/c" excluded, because
     // "a/b/c" does live underneath "a/b".
     WalkableGraph graph = Preconditions.checkNotNull(evaluationResult.getWalkableGraph());
-    SkyKey abKey = createCollectPackagesKey(rootDirectory, new PathFragment("a/b"), excludedPaths);
+    SkyKey abKey = createCollectPackagesKey(
+        rootDirectory, PathFragment.create("a/b"), excludedPaths);
     assertThat(exists(abKey, graph)).isTrue();
     CollectPackagesUnderDirectoryValue abValue =
         (CollectPackagesUnderDirectoryValue) Preconditions.checkNotNull(graph.getValue(abKey));
@@ -252,7 +254,7 @@
     RootedPath abd =
         Iterables.getOnlyElement(
             abValue.getSubdirectoryTransitivelyContainsPackagesOrErrors().keySet());
-    assertThat(abd.getRelativePath()).isEqualTo(new PathFragment("a/b/d"));
+    assertThat(abd.getRelativePath()).isEqualTo(PathFragment.create("a/b/d"));
 
     // And no package is under "a/b/d".
     assertThat(abValue.getSubdirectoryTransitivelyContainsPackagesOrErrors().get(abd)).isFalse();
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 a45d7b1..229cbcf 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
@@ -137,16 +137,16 @@
   }
 
   private Artifact sourceArtifact(String path) {
-    return new Artifact(new PathFragment(path), Root.asSourceRoot(rootDirectory));
+    return new Artifact(PathFragment.create(path), Root.asSourceRoot(rootDirectory));
   }
 
   private Artifact sourceArtifactUnderPackagePath(String path, String packagePath) {
     return new Artifact(
-        new PathFragment(path), Root.asSourceRoot(rootDirectory.getRelative(packagePath)));
+        PathFragment.create(path), Root.asSourceRoot(rootDirectory.getRelative(packagePath)));
   }
 
   private Artifact derivedArtifact(String path) {
-    PathFragment execPath = new PathFragment("out").getRelative(path);
+    PathFragment execPath = PathFragment.create("out").getRelative(path);
     Path fullPath = rootDirectory.getRelative(execPath);
     Artifact output =
         new Artifact(
@@ -161,7 +161,8 @@
   }
 
   private RootedPath rootedPath(String path, String packagePath) {
-    return RootedPath.toRootedPath(rootDirectory.getRelative(packagePath), new PathFragment(path));
+    return RootedPath.toRootedPath(
+        rootDirectory.getRelative(packagePath), PathFragment.create(path));
   }
 
   private static RootedPath childOf(Artifact artifact, String relative) {
@@ -376,7 +377,7 @@
   public void testTraversalOfSymlinkToFile() throws Exception {
     Artifact linkNameArtifact = sourceArtifact("foo/baz/qux.sym");
     Artifact linkTargetArtifact = sourceArtifact("foo/bar/baz.txt");
-    PathFragment linkValue = new PathFragment("../bar/baz.txt");
+    PathFragment linkValue = PathFragment.create("../bar/baz.txt");
     TraversalRequest traversalRoot = fileLikeRoot(linkNameArtifact, DONT_CROSS);
     createFile(linkTargetArtifact);
     scratch.dir(linkNameArtifact.getExecPath().getParentDirectory().getPathString());
@@ -407,8 +408,8 @@
     RootedPath fileA = createFile(rootedPath(sourceArtifact("a/file.a")));
     RootedPath directLink = rootedPath(directLinkArtifact);
     RootedPath transitiveLink = rootedPath(transitiveLinkArtifact);
-    PathFragment directLinkPath = new PathFragment("../a/file.a");
-    PathFragment transitiveLinkPath = new PathFragment("../direct/file.sym");
+    PathFragment directLinkPath = PathFragment.create("../a/file.a");
+    PathFragment transitiveLinkPath = PathFragment.create("../direct/file.sym");
 
     parentOf(directLink).asPath().createDirectory();
     parentOf(transitiveLink).asPath().createDirectory();
@@ -500,8 +501,8 @@
     RootedPath fileA = createFile(rootedPath(sourceArtifact("a/file.a")));
     RootedPath directLink = rootedPath(directLinkArtifact);
     RootedPath transitiveLink = rootedPath(transitiveLinkArtifact);
-    PathFragment directLinkPath = new PathFragment("../a");
-    PathFragment transitiveLinkPath = new PathFragment("../direct/dir.sym");
+    PathFragment directLinkPath = PathFragment.create("../a");
+    PathFragment transitiveLinkPath = PathFragment.create("../direct/dir.sym");
 
     parentOf(directLink).asPath().createDirectory();
     parentOf(transitiveLink).asPath().createDirectory();
@@ -538,7 +539,7 @@
     Artifact linkNameArtifact = sourceArtifact("link/foo.sym");
     Artifact linkTargetArtifact = sourceArtifact("dir");
     RootedPath linkName = rootedPath(linkNameArtifact);
-    PathFragment linkValue = new PathFragment("../dir");
+    PathFragment linkValue = PathFragment.create("../dir");
     RootedPath file1 = createFile(childOf(linkTargetArtifact, "file.1"));
     createFile(childOf(linkTargetArtifact, "sub/file.2"));
     scratch.dir(parentOf(linkName).asPath().getPathString());
@@ -595,7 +596,7 @@
   public void testTraversalOfDanglingSymlink() throws Exception {
     Artifact linkArtifact = sourceArtifact("a/dangling.sym");
     RootedPath link = rootedPath(linkArtifact);
-    PathFragment linkTarget = new PathFragment("non_existent");
+    PathFragment linkTarget = PathFragment.create("non_existent");
     parentOf(link).asPath().createDirectory();
     link.asPath().createSymbolicLink(linkTarget);
     traverseAndAssertFiles(
@@ -607,7 +608,7 @@
     Artifact dirArtifact = sourceArtifact("a");
     RootedPath file = createFile(childOf(dirArtifact, "file.txt"));
     RootedPath link = rootedPath(sourceArtifact("a/dangling.sym"));
-    PathFragment linkTarget = new PathFragment("non_existent");
+    PathFragment linkTarget = PathFragment.create("non_existent");
     parentOf(link).asPath().createDirectory();
     link.asPath().createSymbolicLink(linkTarget);
     traverseAndAssertFiles(
@@ -727,7 +728,7 @@
     // Create a relative symlink pp1://a/b.sym -> b/. It will be resolved to the subdirectory
     // pp1://a/b, even though a package definition pp2://a/b exists.
     RootedPath pp1aBsym = siblingOf(pp1aFileA, "b.sym");
-    pp1aBsym.asPath().createSymbolicLink(new PathFragment("b"));
+    pp1aBsym.asPath().createSymbolicLink(PathFragment.create("b"));
     invalidateDirectory(parentOf(pp1aBsym));
 
     // Traverse //a excluding subpackages. The relative symlink //a/b.sym points to the subdirectory
@@ -738,7 +739,7 @@
         regularFileForTesting(pp1aBuild),
         regularFileForTesting(pp1aFileA),
         regularFileForTesting(childOf(pp1aBsym, "file.fake")),
-        symlinkToDirectoryForTesting(parentOf(pp1bFileFake), pp1aBsym, new PathFragment("b")),
+        symlinkToDirectoryForTesting(parentOf(pp1bFileFake), pp1aBsym, PathFragment.create("b")),
         regularFileForTesting(pp1aSubdirFileB));
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/RecursivePkgFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/RecursivePkgFunctionTest.java
index 89f961a..d23b527 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/RecursivePkgFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/RecursivePkgFunctionTest.java
@@ -92,7 +92,7 @@
   public void testStartingAtBuildFile() throws Exception {
     scratch.file("a/b/c/BUILD");
     RecursivePkgValue value =
-        buildRecursivePkgValue(rootDirectory, new PathFragment("a/b/c/BUILD"));
+        buildRecursivePkgValue(rootDirectory, PathFragment.create("a/b/c/BUILD"));
     assertTrue(value.getPackages().isEmpty());
   }
 
@@ -106,11 +106,11 @@
     scratch.file(root2 + "/a/b/BUILD");
     setPackageCacheOptions("--package_path=" + "root1" + ":" + "root2");
 
-    RecursivePkgValue valueForRoot1 = buildRecursivePkgValue(root1, new PathFragment("a"));
+    RecursivePkgValue valueForRoot1 = buildRecursivePkgValue(root1, PathFragment.create("a"));
     String root1Pkg = Iterables.getOnlyElement(valueForRoot1.getPackages());
     assertEquals(root1Pkg, "a");
 
-    RecursivePkgValue valueForRoot2 = buildRecursivePkgValue(root2, new PathFragment("a"));
+    RecursivePkgValue valueForRoot2 = buildRecursivePkgValue(root2, PathFragment.create("a"));
     String root2Pkg = Iterables.getOnlyElement(valueForRoot2.getPackages());
     assertEquals(root2Pkg, "a/b");
   }
@@ -123,10 +123,10 @@
     scratch.file("a/c/BUILD");
 
     // When the top package is evaluated for recursive package values, and "a/b" is excluded,
-    PathFragment excludedPathFragment = new PathFragment("a/b");
+    PathFragment excludedPathFragment = PathFragment.create("a/b");
     SkyKey key =
         buildRecursivePkgKey(
-            rootDirectory, new PathFragment("a"), ImmutableSet.of(excludedPathFragment));
+            rootDirectory, PathFragment.create("a"), ImmutableSet.of(excludedPathFragment));
     EvaluationResult<RecursivePkgValue> evaluationResult = getEvaluationResult(key);
     RecursivePkgValue value = evaluationResult.get(key);
 
@@ -150,7 +150,7 @@
     assertTrue(
         exists(
             buildRecursivePkgKey(
-                rootDirectory, new PathFragment("a/c"), ImmutableSet.<PathFragment>of()),
+                rootDirectory, PathFragment.create("a/c"), ImmutableSet.<PathFragment>of()),
             graph));
   }
 
@@ -162,8 +162,8 @@
     scratch.file("a/b/d/BUILD");
 
     // When the top package is evaluated for recursive package values, and "a/b/c" is excluded,
-    ImmutableSet<PathFragment> excludedPaths = ImmutableSet.of(new PathFragment("a/b/c"));
-    SkyKey key = buildRecursivePkgKey(rootDirectory, new PathFragment("a"), excludedPaths);
+    ImmutableSet<PathFragment> excludedPaths = ImmutableSet.of(PathFragment.create("a/b/c"));
+    SkyKey key = buildRecursivePkgKey(rootDirectory, PathFragment.create("a"), excludedPaths);
     EvaluationResult<RecursivePkgValue> evaluationResult = getEvaluationResult(key);
     RecursivePkgValue value = evaluationResult.get(key);
 
@@ -178,6 +178,8 @@
     // "a/b/c" does live underneath "a/b".
     WalkableGraph graph = Preconditions.checkNotNull(evaluationResult.getWalkableGraph());
     assertTrue(
-        exists(buildRecursivePkgKey(rootDirectory, new PathFragment("a/b"), excludedPaths), graph));
+        exists(
+            buildRecursivePkgKey(rootDirectory, PathFragment.create("a/b"), excludedPaths),
+            graph));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/RecursivePkgKeyTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/RecursivePkgKeyTest.java
index 9d0fc4d..e205cab 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/RecursivePkgKeyTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/RecursivePkgKeyTest.java
@@ -53,37 +53,37 @@
   public void testValidRecursivePkgKeys() throws Exception {
     buildRecursivePkgKey(
         RepositoryName.MAIN,
-        new PathFragment(""),
+        PathFragment.create(""),
         ImmutableSet.<PathFragment>of());
     buildRecursivePkgKey(
         RepositoryName.MAIN,
-        new PathFragment(""),
-        ImmutableSet.of(new PathFragment("a")));
+        PathFragment.create(""),
+        ImmutableSet.of(PathFragment.create("a")));
 
     buildRecursivePkgKey(
         RepositoryName.MAIN,
-        new PathFragment("a"),
+        PathFragment.create("a"),
         ImmutableSet.<PathFragment>of());
     buildRecursivePkgKey(
         RepositoryName.MAIN,
-        new PathFragment("a"),
-        ImmutableSet.of(new PathFragment("a/b")));
+        PathFragment.create("a"),
+        ImmutableSet.of(PathFragment.create("a/b")));
 
     buildRecursivePkgKey(
         RepositoryName.MAIN,
-        new PathFragment("a/b"),
+        PathFragment.create("a/b"),
         ImmutableSet.<PathFragment>of());
     buildRecursivePkgKey(
         RepositoryName.MAIN,
-        new PathFragment("a/b"),
-        ImmutableSet.of(new PathFragment("a/b/c")));
+        PathFragment.create("a/b"),
+        ImmutableSet.of(PathFragment.create("a/b/c")));
   }
 
   @Test
   public void testInvalidRecursivePkgKeys() throws Exception {
-    invalidHelper(new PathFragment(""), ImmutableSet.of(new PathFragment("")));
-    invalidHelper(new PathFragment("a"), ImmutableSet.of(new PathFragment("a")));
-    invalidHelper(new PathFragment("a"), ImmutableSet.of(new PathFragment("b")));
-    invalidHelper(new PathFragment("a/b"), ImmutableSet.of(new PathFragment("a")));
+    invalidHelper(PathFragment.create(""), ImmutableSet.of(PathFragment.create("")));
+    invalidHelper(PathFragment.create("a"), ImmutableSet.of(PathFragment.create("a")));
+    invalidHelper(PathFragment.create("a"), ImmutableSet.of(PathFragment.create("b")));
+    invalidHelper(PathFragment.create("a/b"), ImmutableSet.of(PathFragment.create("a")));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java
index 66c469d..9c73d2f 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java
@@ -443,7 +443,7 @@
 
   private RootedPath createSkyframeDepOfAction() throws Exception {
     scratch.file(rootDirectory.getRelative("action.dep").getPathString(), "blah");
-    return RootedPath.toRootedPath(rootDirectory, new PathFragment("action.dep"));
+    return RootedPath.toRootedPath(rootDirectory, PathFragment.create("action.dep"));
   }
 
   private void appendToFile(Path path) throws Exception {
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeLabelVisitorTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeLabelVisitorTest.java
index 892f721..8aad421 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeLabelVisitorTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeLabelVisitorTest.java
@@ -261,8 +261,8 @@
     scratch.file("x/y/BUILD", "sh_library(name = 'z')");
     syncPackages(
         ModifiedFileSet.builder()
-            .modify(new PathFragment("x/y"))
-            .modify(new PathFragment("x/y/BUILD"))
+            .modify(PathFragment.create("x/y"))
+            .modify(PathFragment.create("x/y/BUILD"))
             .build());
 
     reporter.removeHandler(failFastHandler); // expect errors
@@ -281,7 +281,7 @@
     assertContainsEvent("Label '//x:y/z' crosses boundary of subpackage 'x/y'");
 
     scratch.deleteFile("x/y/BUILD");
-    syncPackages(ModifiedFileSet.builder().modify(new PathFragment("x/y/BUILD")).build());
+    syncPackages(ModifiedFileSet.builder().modify(PathFragment.create("x/y/BUILD")).build());
 
     reporter.addHandler(failFastHandler); // don't expect errors
     assertLabelsVisited(
@@ -474,14 +474,14 @@
         ImmutableSet.of("//a:a"), ImmutableSet.of("//a:a"), !EXPECT_ERROR, !KEEP_GOING);
 
     Path subpackageBuildFile = scratch.file("b/c/BUILD", "exports_files(['foo'])");
-    syncPackages(ModifiedFileSet.builder().modify(new PathFragment("b/c/BUILD")).build());
+    syncPackages(ModifiedFileSet.builder().modify(PathFragment.create("b/c/BUILD")).build());
 
     reporter.removeHandler(failFastHandler); // expect errors
     assertLabelsVisitedWithErrors(ImmutableSet.of("//a:a"), ImmutableSet.of("//a:a"));
     assertContainsEvent("Label '//b:c/d/foo' crosses boundary of subpackage 'b/c'");
 
     subpackageBuildFile.delete();
-    syncPackages(ModifiedFileSet.builder().modify(new PathFragment("b/c/BUILD")).build());
+    syncPackages(ModifiedFileSet.builder().modify(PathFragment.create("b/c/BUILD")).build());
 
     assertLabelsVisited(
         ImmutableSet.of("//a:a"), ImmutableSet.of("//a:a"), !EXPECT_ERROR, !KEEP_GOING);
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TargetMarkerFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TargetMarkerFunctionTest.java
index d4dda9b..5561adc 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/TargetMarkerFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/TargetMarkerFunctionTest.java
@@ -93,7 +93,7 @@
 
     scratch.file("a/b/BUILD");
     ModifiedFileSet subpackageBuildFile =
-        ModifiedFileSet.builder().modify(new PathFragment("a/b/BUILD")).build();
+        ModifiedFileSet.builder().modify(PathFragment.create("a/b/BUILD")).build();
     skyframeExecutor.invalidateFilesUnderPathForTesting(
         reporter, subpackageBuildFile, rootDirectory);
 
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 8caead9..4b6b700 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
@@ -309,7 +309,7 @@
 
   Artifact createSourceArtifact(FileSystem fs, String name) {
     Path root = fs.getPath(TestUtils.tmpDir());
-    return new Artifact(new PathFragment(name), Root.asSourceRoot(root));
+    return new Artifact(PathFragment.create(name), Root.asSourceRoot(root));
   }
 
   protected Artifact createDerivedArtifact(String name) {
@@ -318,7 +318,7 @@
 
   Artifact createDerivedArtifact(FileSystem fs, String name) {
     Path execRoot = fs.getPath(TestUtils.tmpDir());
-    PathFragment execPath = new PathFragment("out").getRelative(name);
+    PathFragment execPath = PathFragment.create("out").getRelative(name);
     Path path = execRoot.getRelative(execPath);
     return new Artifact(
         path, Root.asDerivedRoot(execRoot, execRoot.getRelative("out")), execPath, ALL_OWNER);
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 99da8b9..c682340 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
@@ -709,9 +709,9 @@
     // artifact1 is a tree artifact generated by a TouchingTestAction.
     Artifact artifact1 = createTreeArtifact("treeArtifact1");
     TreeFileArtifact treeFileArtifactA = ActionInputHelper.treeFileArtifact(
-        artifact1, new PathFragment("child1"));
+        artifact1, PathFragment.create("child1"));
     TreeFileArtifact treeFileArtifactB = ActionInputHelper.treeFileArtifact(
-        artifact1, new PathFragment("child2"));
+        artifact1, PathFragment.create("child2"));
     registerAction(new TouchingTestAction(treeFileArtifactA, treeFileArtifactB));
 
     // artifact2 is a tree artifact generated by an action template.
@@ -723,9 +723,9 @@
     // We mock out the action template function to expand into two actions that just touch the
     // output files.
     TreeFileArtifact expectedOutputTreeFileArtifact1 = ActionInputHelper.treeFileArtifact(
-        artifact2, new PathFragment("child1"));
+        artifact2, PathFragment.create("child1"));
     TreeFileArtifact expectedOutputTreeFileArtifact2 = ActionInputHelper.treeFileArtifact(
-        artifact2, new PathFragment("child2"));
+        artifact2, PathFragment.create("child2"));
     Action generateOutputAction = new DummyAction(
         ImmutableList.<Artifact>of(treeFileArtifactA), expectedOutputTreeFileArtifact1);
     Action noGenerateOutputAction = new DummyAction(
@@ -747,9 +747,9 @@
     // artifact1 is a tree artifact generated by a TouchingTestAction.
     Artifact artifact1 = createTreeArtifact("treeArtifact1");
     TreeFileArtifact treeFileArtifactA = ActionInputHelper.treeFileArtifact(
-        artifact1, new PathFragment("child1"));
+        artifact1, PathFragment.create("child1"));
     TreeFileArtifact treeFileArtifactB = ActionInputHelper.treeFileArtifact(
-        artifact1, new PathFragment("child2"));
+        artifact1, PathFragment.create("child2"));
     registerAction(new TouchingTestAction(treeFileArtifactA, treeFileArtifactB));
 
     // artifact2 is a tree artifact generated by an action template.
@@ -762,9 +762,9 @@
     // One Action that touches the output file.
     // The other action that does not generate the output file.
     TreeFileArtifact expectedOutputTreeFileArtifact1 = ActionInputHelper.treeFileArtifact(
-        artifact2, new PathFragment("child1"));
+        artifact2, PathFragment.create("child1"));
     TreeFileArtifact expectedOutputTreeFileArtifact2 = ActionInputHelper.treeFileArtifact(
-        artifact2, new PathFragment("child2"));
+        artifact2, PathFragment.create("child2"));
     Action generateOutputAction = new DummyAction(
         ImmutableList.<Artifact>of(treeFileArtifactA), expectedOutputTreeFileArtifact1);
     Action noGenerateOutputAction = new NoOpDummyAction(
@@ -792,9 +792,9 @@
     // artifact1 is a tree artifact generated by a TouchingTestAction.
     Artifact artifact1 = createTreeArtifact("treeArtifact1");
     TreeFileArtifact treeFileArtifactA = ActionInputHelper.treeFileArtifact(
-        artifact1, new PathFragment("child1"));
+        artifact1, PathFragment.create("child1"));
     TreeFileArtifact treeFileArtifactB = ActionInputHelper.treeFileArtifact(
-        artifact1, new PathFragment("child2"));
+        artifact1, PathFragment.create("child2"));
     registerAction(new TouchingTestAction(treeFileArtifactA, treeFileArtifactB));
 
     // artifact2 is a tree artifact generated by an action template.
@@ -807,9 +807,9 @@
     // One Action that touches the output file.
     // The other action that just throws when executed.
     TreeFileArtifact expectedOutputTreeFileArtifact1 = ActionInputHelper.treeFileArtifact(
-        artifact2, new PathFragment("child1"));
+        artifact2, PathFragment.create("child1"));
     TreeFileArtifact expectedOutputTreeFileArtifact2 = ActionInputHelper.treeFileArtifact(
-        artifact2, new PathFragment("child2"));
+        artifact2, PathFragment.create("child2"));
     Action generateOutputAction = new DummyAction(
         ImmutableList.<Artifact>of(treeFileArtifactA), expectedOutputTreeFileArtifact1);
     Action throwingAction = new ThrowingDummyAction(
@@ -837,9 +837,9 @@
     // artifact1 is a tree artifact generated by a TouchingTestAction.
     Artifact artifact1 = createTreeArtifact("treeArtifact1");
     TreeFileArtifact treeFileArtifactA = ActionInputHelper.treeFileArtifact(
-        artifact1, new PathFragment("child1"));
+        artifact1, PathFragment.create("child1"));
     TreeFileArtifact treeFileArtifactB = ActionInputHelper.treeFileArtifact(
-        artifact1, new PathFragment("child2"));
+        artifact1, PathFragment.create("child2"));
     registerAction(new TouchingTestAction(treeFileArtifactA, treeFileArtifactB));
 
     // artifact2 is a tree artifact generated by an action template.
@@ -850,9 +850,9 @@
 
     // We mock out the action template function to expand into two actions that throw when executed.
     TreeFileArtifact expectedOutputTreeFileArtifact1 = ActionInputHelper.treeFileArtifact(
-        artifact2, new PathFragment("child1"));
+        artifact2, PathFragment.create("child1"));
     TreeFileArtifact expectedOutputTreeFileArtifact2 = ActionInputHelper.treeFileArtifact(
-        artifact2, new PathFragment("child2"));
+        artifact2, PathFragment.create("child2"));
     Action throwingAction = new ThrowingDummyAction(
         ImmutableList.<Artifact>of(treeFileArtifactA),
         ImmutableList.<Artifact>of(expectedOutputTreeFileArtifact1));
@@ -1044,7 +1044,7 @@
 
     void registerOutput(ActionExecutionContext context, String outputName) throws IOException {
       context.getMetadataHandler().addExpandedTreeOutput(
-          treeFileArtifact(getSoleOutput(), new PathFragment(outputName)));
+          treeFileArtifact(getSoleOutput(), PathFragment.create(outputName)));
     }
 
     static List<TreeFileArtifact> asTreeFileArtifacts(final Artifact parent, String... files) {
@@ -1158,7 +1158,7 @@
   private Artifact createTreeArtifact(String name) {
     FileSystem fs = scratch.getFileSystem();
     Path execRoot = fs.getPath(TestUtils.tmpDir());
-    PathFragment execPath = new PathFragment("out").getRelative(name);
+    PathFragment execPath = PathFragment.create("out").getRelative(name);
     Path path = execRoot.getRelative(execPath);
     return new SpecialArtifact(
         path, Root.asDerivedRoot(execRoot, execRoot.getRelative("out")), execPath, ALL_OWNER,
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 03d6618..56bf8a5 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
@@ -124,7 +124,7 @@
   public void testEqualTreeArtifacts() throws Exception {
     Artifact treeArtifact = createTreeArtifact("out");
     ImmutableList<PathFragment> children =
-        ImmutableList.of(new PathFragment("one"), new PathFragment("two"));
+        ImmutableList.of(PathFragment.create("one"), PathFragment.create("two"));
     TreeArtifactValue valueOne = evaluateTreeArtifact(treeArtifact, children);
     MemoizingEvaluator evaluator = driver.getGraphForTesting();
     evaluator.delete(new Predicate<SkyKey>() {
@@ -142,18 +142,18 @@
   @Test
   public void testTreeArtifactsWithDigests() throws Exception {
     fastDigest = true;
-    doTestTreeArtifacts(ImmutableList.of(new PathFragment("one")));
+    doTestTreeArtifacts(ImmutableList.of(PathFragment.create("one")));
   }
 
   @Test
   public void testTreeArtifactsWithoutDigests() throws Exception {
     fastDigest = false;
-    doTestTreeArtifacts(ImmutableList.of(new PathFragment("one")));
+    doTestTreeArtifacts(ImmutableList.of(PathFragment.create("one")));
   }
 
   @Test
   public void testTreeArtifactMultipleDigests() throws Exception {
-    doTestTreeArtifacts(ImmutableList.of(new PathFragment("one"), new PathFragment("two")));
+    doTestTreeArtifacts(ImmutableList.of(PathFragment.create("one"), PathFragment.create("two")));
   }
 
   @Test
@@ -162,7 +162,7 @@
     Artifact one = createTreeArtifact("outOne");
     Artifact two = createTreeArtifact("outTwo");
     ImmutableList<PathFragment> children =
-        ImmutableList.of(new PathFragment("one"), new PathFragment("two"));
+        ImmutableList.of(PathFragment.create("one"), PathFragment.create("two"));
     TreeArtifactValue valueOne = evaluateTreeArtifact(one, children);
     TreeArtifactValue valueTwo = evaluateTreeArtifact(two, children);
     assertThat(valueOne.getDigest()).isEqualTo(valueTwo.getDigest());
@@ -188,7 +188,7 @@
     try {
       Artifact artifact = createTreeArtifact("outOne");
       TreeArtifactValue value = evaluateTreeArtifact(artifact,
-          ImmutableList.of(new PathFragment("one")));
+          ImmutableList.of(PathFragment.create("one")));
       fail("MissingInputFileException expected, got " + value);
     } catch (Exception e) {
       assertThat(Throwables.getRootCause(e).getMessage()).contains(exception.getMessage());
@@ -201,7 +201,7 @@
   }
 
   private Artifact createTreeArtifact(String path) throws IOException {
-    PathFragment execPath = new PathFragment("out").getRelative(path);
+    PathFragment execPath = PathFragment.create("out").getRelative(path);
     Path fullPath = root.getRelative(execPath);
     Artifact output =
         new SpecialArtifact(
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunctionTest.java
index 832cb1c..95e1a62 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunctionTest.java
@@ -60,7 +60,7 @@
     Path workspacePath = scratch.overwriteFile("WORKSPACE", contents);
     fakeWorkspaceFileValue.setSize(workspacePath.getFileSize());
     return RootedPath.toRootedPath(
-        workspacePath.getParentDirectory(), new PathFragment(workspacePath.getBaseName()));
+        workspacePath.getParentDirectory(), PathFragment.create(workspacePath.getBaseName()));
   }
 
   private SkyFunction.Environment getEnv() throws InterruptedException {
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java
index 0f5e046..714c662 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java
@@ -124,7 +124,7 @@
     Path workspacePath = scratch.overwriteFile("WORKSPACE", contents);
     fakeWorkspaceFileValue.setSize(workspacePath.getFileSize());
     return RootedPath.toRootedPath(
-        workspacePath.getParentDirectory(), new PathFragment(workspacePath.getBaseName()));
+        workspacePath.getParentDirectory(), PathFragment.create(workspacePath.getBaseName()));
   }
 
   // Dummy harmcrest matcher that match the function name of a skykey
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunctionTest.java
index fbb1e64..589a53c 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunctionTest.java
@@ -36,7 +36,7 @@
   private EvaluationResult<WorkspaceNameValue> eval() throws InterruptedException {
     getSkyframeExecutor().invalidateFilesUnderPathForTesting(
         reporter,
-        ModifiedFileSet.builder().modify(new PathFragment("WORKSPACE")).build(),
+        ModifiedFileSet.builder().modify(PathFragment.create("WORKSPACE")).build(),
         rootDirectory);
     return SkyframeExecutorTestUtils.evaluate(
         getSkyframeExecutor(), key, /*keepGoing=*/ false, reporter);
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java b/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java
index 71e9cec..5ad7027 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java
@@ -243,8 +243,8 @@
       }
     }
     DummyFreezable dummy = new DummyFreezable();
-    Location locA = Location.fromPathFragment(new PathFragment("/a"));
-    Location locB = Location.fromPathFragment(new PathFragment("/b"));
+    Location locA = Location.fromPathFragment(PathFragment.create("/a"));
+    Location locB = Location.fromPathFragment(PathFragment.create("/b"));
     Environment env = Environment.builder(mutability).build();
 
     // Acquire two locks, release two locks, check along the way.
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/LexerTest.java b/src/test/java/com/google/devtools/build/lib/syntax/LexerTest.java
index 10da1ad..b270a54 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/LexerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/LexerTest.java
@@ -41,7 +41,7 @@
    * error handler beforehand.
    */
   private Lexer createLexer(String input) {
-    PathFragment somePath = new PathFragment("/some/path.txt");
+    PathFragment somePath = PathFragment.create("/some/path.txt");
     ParserInputSource inputSource = ParserInputSource.create(input, somePath);
     Reporter reporter = new Reporter(new EventBus());
     reporter.addHandler(new EventHandler() {
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/LineNumberTableTest.java b/src/test/java/com/google/devtools/build/lib/syntax/LineNumberTableTest.java
index c461635..4377b35 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/LineNumberTableTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/LineNumberTableTest.java
@@ -29,7 +29,7 @@
 @RunWith(JUnit4.class)
 public class LineNumberTableTest {
   private LineNumberTable create(String buffer) {
-    return LineNumberTable.create(buffer.toCharArray(), new PathFragment("/fake/file"));
+    return LineNumberTable.create(buffer.toCharArray(), PathFragment.create("/fake/file"));
   }
 
   @Test
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/ParserInputSourceTest.java b/src/test/java/com/google/devtools/build/lib/syntax/ParserInputSourceTest.java
index d93fc6a..467a5ba 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/ParserInputSourceTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/ParserInputSourceTest.java
@@ -50,7 +50,7 @@
   public void testCreateFromString() {
     String content = "Content provided as a string.";
     String pathName = "/the/name/of/the/content.txt";
-    ParserInputSource input = ParserInputSource.create(content, new PathFragment(pathName));
+    ParserInputSource input = ParserInputSource.create(content, PathFragment.create(pathName));
     assertEquals(content, new String(input.getContent()));
     assertEquals(pathName, input.getPath().toString());
   }
@@ -60,7 +60,7 @@
     String content = "Content provided as a string.";
     String pathName = "/the/name/of/the/content.txt";
     char[] contentChars = content.toCharArray();
-    ParserInputSource input = ParserInputSource.create(contentChars, new PathFragment(pathName));
+    ParserInputSource input = ParserInputSource.create(contentChars, PathFragment.create(pathName));
     assertEquals(content, new String(input.getContent()));
     assertEquals(pathName, input.getPath().toString());
   }
@@ -81,12 +81,12 @@
   @Test
   public void testWillNotTryToReadInputFileIfContentProvidedAsString() {
     ParserInputSource.create(
-        "Content provided as string.", new PathFragment("/will/not/try/to/read"));
+        "Content provided as string.", PathFragment.create("/will/not/try/to/read"));
   }
 
   @Test
   public void testWillNotTryToReadInputFileIfContentProvidedAsChars() {
     char[] content = "Content provided as char array.".toCharArray();
-    ParserInputSource.create(content, new PathFragment("/will/not/try/to/read"));
+    ParserInputSource.create(content, PathFragment.create("/will/not/try/to/read"));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java b/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
index db96a9d..e107d1b 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
@@ -1025,7 +1025,7 @@
     assertThat(imp.getImportString()).named("getImportString()").isEqualTo("/some/skylark/file");
     assertThat(imp.hasAbsolutePath()).named("hasAbsolutePath()").isTrue();
     assertThat(imp.getAbsolutePath()).named("getAbsolutePath()")
-        .isEqualTo(new PathFragment("/some/skylark/file.bzl"));
+        .isEqualTo(PathFragment.create("/some/skylark/file.bzl"));
 
     int startOffset = stmt.getImport().getLocation().getStartOffset();
     int endOffset = stmt.getImport().getLocation().getEndOffset();
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkImportTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkImportTest.java
index 49fdd73..fa9dfbf 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkImportTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkImportTest.java
@@ -46,7 +46,7 @@
         .isEqualTo(Label.parseAbsoluteUnchecked(expectedLabelString));
  
     assertThat(importForLabel.asPathFragment()).named("asPathFragment()")
-        .isEqualTo(new PathFragment(expectedPathString));
+        .isEqualTo(PathFragment.create(expectedPathString));
 
     thrown.expect(IllegalStateException.class);
     importForLabel.getAbsolutePath();   
@@ -76,10 +76,10 @@
 
     Label irrelevantContainingFile = Label.parseAbsoluteUnchecked("//another/path:BUILD");
     assertThat(importForPath.getAbsolutePath()).named("getAbsolutePath()")
-        .isEqualTo(new PathFragment("//some/skylark/file.bzl"));
+        .isEqualTo(PathFragment.create("//some/skylark/file.bzl"));
 
      assertThat(importForPath.asPathFragment()).named("asPathFragment()")
-        .isEqualTo(new PathFragment("/some/skylark/file.bzl"));
+        .isEqualTo(PathFragment.create("/some/skylark/file.bzl"));
 
     thrown.expect(IllegalStateException.class);
     importForPath.getLabel(irrelevantContainingFile);
@@ -99,7 +99,7 @@
         .isEqualTo(Label.parseAbsolute(expectedLabelString));
 
     assertThat(importForLabel.asPathFragment()).named("asPathFragment()")
-        .isEqualTo(new PathFragment(expectedPathString));
+        .isEqualTo(PathFragment.create(expectedPathString));
 
    thrown.expect(IllegalStateException.class);
     importForLabel.getAbsolutePath();
@@ -149,7 +149,7 @@
         .isEqualTo(Label.parseAbsolute(expectedLabelString));
     
     assertThat(importForPath.asPathFragment()).named("asPathFragment()")
-        .isEqualTo(new PathFragment(expectedPathString));
+        .isEqualTo(PathFragment.create(expectedPathString));
 
     thrown.expect(IllegalStateException.class);
     importForPath.getAbsolutePath();
diff --git a/src/test/java/com/google/devtools/build/lib/util/FileTypeTest.java b/src/test/java/com/google/devtools/build/lib/util/FileTypeTest.java
index fd05190..67bdfe2 100644
--- a/src/test/java/com/google/devtools/build/lib/util/FileTypeTest.java
+++ b/src/test/java/com/google/devtools/build/lib/util/FileTypeTest.java
@@ -97,7 +97,7 @@
 
   @Test
   public void handlesPathFragmentObjects() {
-    PathFragment readme = new PathFragment("some/where/readme.txt");
+    PathFragment readme = PathFragment.create("some/where/readme.txt");
     assertTrue(TEXT.matches(readme));
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/util/FingerprintTest.java b/src/test/java/com/google/devtools/build/lib/util/FingerprintTest.java
index faf9745..d1806ee 100644
--- a/src/test/java/com/google/devtools/build/lib/util/FingerprintTest.java
+++ b/src/test/java/com/google/devtools/build/lib/util/FingerprintTest.java
@@ -112,7 +112,7 @@
 
   @Test
   public void addPath() throws Exception {
-    PathFragment pf = new PathFragment("/etc/pwd");
+    PathFragment pf = PathFragment.create("/etc/pwd");
     assertThat(new Fingerprint().addPath(pf).hexDigestAndReset())
         .isEqualTo("63ab5c47c117635407a1af6377e216bc");
     Path p = new InMemoryFileSystem(BlazeClock.instance()).getPath(pf);
@@ -161,8 +161,8 @@
         .addNullableBoolean(null)
         .addNullableInt(null)
         .addNullableString(null)
-        .addPath(new PathFragment("/foo/bar"))
-        .addPaths(ImmutableList.of(new PathFragment("/foo/bar")))
+        .addPath(PathFragment.create("/foo/bar"))
+        .addPaths(ImmutableList.of(PathFragment.create("/foo/bar")))
         .addString("baz")
         .addUUID(UUID.fromString("12345678-1234-1234-1234-1234567890ab"))
         .hexDigestAndReset();
diff --git a/src/test/java/com/google/devtools/build/lib/util/OptionsUtilsTest.java b/src/test/java/com/google/devtools/build/lib/util/OptionsUtilsTest.java
index 9995dfc..84030ad 100644
--- a/src/test/java/com/google/devtools/build/lib/util/OptionsUtilsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/util/OptionsUtilsTest.java
@@ -124,7 +124,7 @@
   }
 
   private PathFragment fragment(String string) {
-    return new PathFragment(string);
+    return PathFragment.create(string);
   }
 
   private List<PathFragment> convert(String input) throws Exception {
@@ -155,7 +155,7 @@
   @Test
   public void valueisUnmodifiable() throws Exception {
     try {
-      new PathFragmentListConverter().convert("value").add(new PathFragment("other"));
+      new PathFragmentListConverter().convert("value").add(PathFragment.create("other"));
       fail("could modify value");
     } catch (UnsupportedOperationException expected) {}
   }
diff --git a/src/test/java/com/google/devtools/build/lib/util/PathFragmentFilterTest.java b/src/test/java/com/google/devtools/build/lib/util/PathFragmentFilterTest.java
index 134c7a5..3f25414 100644
--- a/src/test/java/com/google/devtools/build/lib/util/PathFragmentFilterTest.java
+++ b/src/test/java/com/google/devtools/build/lib/util/PathFragmentFilterTest.java
@@ -35,11 +35,11 @@
   }
 
   protected void assertIncluded(String path) {
-    assertTrue(filter.isIncluded(new PathFragment(path)));
+    assertTrue(filter.isIncluded(PathFragment.create(path)));
   }
 
   protected void assertExcluded(String path) {
-    assertFalse(filter.isIncluded(new PathFragment(path)));
+    assertFalse(filter.isIncluded(PathFragment.create(path)));
   }
 
   @Test
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/FileSystemTest.java b/src/test/java/com/google/devtools/build/lib/vfs/FileSystemTest.java
index 8b4255b..0a1d052 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/FileSystemTest.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/FileSystemTest.java
@@ -306,7 +306,7 @@
   @Test
   public void testCreatePathRelativeToWorkingDirectory() {
     Path relativeCreatedPath = absolutize("some-file");
-    Path expectedResult = workingDir.getRelative(new PathFragment("some-file"));
+    Path expectedResult = workingDir.getRelative(PathFragment.create("some-file"));
 
     assertEquals(expectedResult, relativeCreatedPath);
   }
@@ -1091,7 +1091,7 @@
   @Test
   public void testGetPathOnlyAcceptsAbsolutePathFragment() {
     try {
-      testFS.getPath(new PathFragment("not-absolute"));
+      testFS.getPath(PathFragment.create("not-absolute"));
       fail("The expected Exception was not thrown.");
     } catch (IllegalArgumentException ex) {
       assertThat(ex).hasMessage("not-absolute (not an absolute path)");
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/FileSystemUtilsTest.java b/src/test/java/com/google/devtools/build/lib/vfs/FileSystemUtilsTest.java
index f9f4850..421b9fb 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/FileSystemUtilsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/FileSystemUtilsTest.java
@@ -227,69 +227,70 @@
   @Test
   public void testReplaceExtension_PathFragment() throws Exception {
     assertPath("foo/bar.baz",
-               FileSystemUtils.replaceExtension(new PathFragment("foo/bar"), ".baz"));
+               FileSystemUtils.replaceExtension(PathFragment.create("foo/bar"), ".baz"));
     assertPath("foo/bar.baz",
-               FileSystemUtils.replaceExtension(new PathFragment("foo/bar.cc"), ".baz"));
+               FileSystemUtils.replaceExtension(PathFragment.create("foo/bar.cc"), ".baz"));
     assertPath("/foo/bar.baz",
-               FileSystemUtils.replaceExtension(new PathFragment("/foo/bar"), ".baz"));
+               FileSystemUtils.replaceExtension(PathFragment.create("/foo/bar"), ".baz"));
     assertPath("/foo/bar.baz",
-               FileSystemUtils.replaceExtension(new PathFragment("/foo/bar.cc"), ".baz"));
-    assertPath("foo.baz", FileSystemUtils.replaceExtension(new PathFragment("foo/"), ".baz"));
-    assertPath("foo.baz", FileSystemUtils.replaceExtension(new PathFragment("foo.cc/"), ".baz"));
-    assertPath("/foo.baz", FileSystemUtils.replaceExtension(new PathFragment("/foo/"), ".baz"));
+               FileSystemUtils.replaceExtension(PathFragment.create("/foo/bar.cc"), ".baz"));
+    assertPath("foo.baz", FileSystemUtils.replaceExtension(PathFragment.create("foo/"), ".baz"));
+    assertPath("foo.baz", FileSystemUtils.replaceExtension(PathFragment.create("foo.cc/"), ".baz"));
+    assertPath("/foo.baz", FileSystemUtils.replaceExtension(PathFragment.create("/foo/"), ".baz"));
     assertPath("/foo.baz",
-               FileSystemUtils.replaceExtension(new PathFragment("/foo.cc/"), ".baz"));
-    assertPath("foo.baz", FileSystemUtils.replaceExtension(new PathFragment("foo"), ".baz"));
-    assertPath("foo.baz", FileSystemUtils.replaceExtension(new PathFragment("foo.cc"), ".baz"));
-    assertPath("/foo.baz", FileSystemUtils.replaceExtension(new PathFragment("/foo"), ".baz"));
+               FileSystemUtils.replaceExtension(PathFragment.create("/foo.cc/"), ".baz"));
+    assertPath("foo.baz", FileSystemUtils.replaceExtension(PathFragment.create("foo"), ".baz"));
+    assertPath("foo.baz", FileSystemUtils.replaceExtension(PathFragment.create("foo.cc"), ".baz"));
+    assertPath("/foo.baz", FileSystemUtils.replaceExtension(PathFragment.create("/foo"), ".baz"));
     assertPath("/foo.baz",
-               FileSystemUtils.replaceExtension(new PathFragment("/foo.cc"), ".baz"));
-    assertPath(".baz", FileSystemUtils.replaceExtension(new PathFragment(".cc"), ".baz"));
-    assertNull(FileSystemUtils.replaceExtension(new PathFragment("/"), ".baz"));
-    assertNull(FileSystemUtils.replaceExtension(new PathFragment(""), ".baz"));
+               FileSystemUtils.replaceExtension(PathFragment.create("/foo.cc"), ".baz"));
+    assertPath(".baz", FileSystemUtils.replaceExtension(PathFragment.create(".cc"), ".baz"));
+    assertNull(FileSystemUtils.replaceExtension(PathFragment.create("/"), ".baz"));
+    assertNull(FileSystemUtils.replaceExtension(PathFragment.create(""), ".baz"));
     assertPath("foo/bar.baz",
-        FileSystemUtils.replaceExtension(new PathFragment("foo/bar.pony"), ".baz", ".pony"));
+        FileSystemUtils.replaceExtension(PathFragment.create("foo/bar.pony"), ".baz", ".pony"));
     assertPath("foo/bar.baz",
-        FileSystemUtils.replaceExtension(new PathFragment("foo/bar"), ".baz", ""));
-    assertNull(FileSystemUtils.replaceExtension(new PathFragment(""), ".baz", ".pony"));
+        FileSystemUtils.replaceExtension(PathFragment.create("foo/bar"), ".baz", ""));
+    assertNull(FileSystemUtils.replaceExtension(PathFragment.create(""), ".baz", ".pony"));
     assertNull(
-        FileSystemUtils.replaceExtension(new PathFragment("foo/bar.pony"), ".baz", ".unicorn"));
+        FileSystemUtils.replaceExtension(PathFragment.create("foo/bar.pony"), ".baz", ".unicorn"));
   }
 
   @Test
   public void testAppendWithoutExtension() throws Exception {
     assertPath("libfoo-src.jar",
-        appendWithoutExtension(new PathFragment("libfoo.jar"), "-src"));
+        appendWithoutExtension(PathFragment.create("libfoo.jar"), "-src"));
     assertPath("foo/libfoo-src.jar",
-        appendWithoutExtension(new PathFragment("foo/libfoo.jar"), "-src"));
+        appendWithoutExtension(PathFragment.create("foo/libfoo.jar"), "-src"));
     assertPath("java/com/google/foo/libfoo-src.jar",
-        appendWithoutExtension(new PathFragment("java/com/google/foo/libfoo.jar"), "-src"));
+        appendWithoutExtension(PathFragment.create("java/com/google/foo/libfoo.jar"), "-src"));
     assertPath("libfoo.bar-src.jar",
-        appendWithoutExtension(new PathFragment("libfoo.bar.jar"), "-src"));
+        appendWithoutExtension(PathFragment.create("libfoo.bar.jar"), "-src"));
     assertPath("libfoo-src",
-        appendWithoutExtension(new PathFragment("libfoo"), "-src"));
+        appendWithoutExtension(PathFragment.create("libfoo"), "-src"));
     assertPath("libfoo-src.jar",
-        appendWithoutExtension(new PathFragment("libfoo.jar/"), "-src"));
+        appendWithoutExtension(PathFragment.create("libfoo.jar/"), "-src"));
     assertPath("libfoo.src.jar",
-        appendWithoutExtension(new PathFragment("libfoo.jar"), ".src"));
-    assertNull(appendWithoutExtension(new PathFragment("/"), "-src"));
-    assertNull(appendWithoutExtension(new PathFragment(""), "-src"));
+        appendWithoutExtension(PathFragment.create("libfoo.jar"), ".src"));
+    assertNull(appendWithoutExtension(PathFragment.create("/"), "-src"));
+    assertNull(appendWithoutExtension(PathFragment.create(""), "-src"));
   }
 
   @Test
   public void testReplaceSegments() {
     assertPath(
         "poo/bar/baz.cc",
-        FileSystemUtils.replaceSegments(new PathFragment("foo/bar/baz.cc"), "foo", "poo", true));
+        FileSystemUtils.replaceSegments(PathFragment.create("foo/bar/baz.cc"), "foo", "poo", true));
     assertPath(
         "poo/poo/baz.cc",
-        FileSystemUtils.replaceSegments(new PathFragment("foo/foo/baz.cc"), "foo", "poo", true));
+        FileSystemUtils.replaceSegments(PathFragment.create("foo/foo/baz.cc"), "foo", "poo", true));
     assertPath(
         "poo/foo/baz.cc",
-        FileSystemUtils.replaceSegments(new PathFragment("foo/foo/baz.cc"), "foo", "poo", false));
+        FileSystemUtils.replaceSegments(
+            PathFragment.create("foo/foo/baz.cc"), "foo", "poo", false));
     assertPath(
         "foo/bar/baz.cc",
-        FileSystemUtils.replaceSegments(new PathFragment("foo/bar/baz.cc"), "boo", "poo", true));
+        FileSystemUtils.replaceSegments(PathFragment.create("foo/bar/baz.cc"), "boo", "poo", true));
   }
 
   @Test
@@ -308,11 +309,11 @@
 
   @Test
   public void testResolveRelativeToFilesystemWorkingDir() {
-    PathFragment relativePath = new PathFragment("relative/path");
+    PathFragment relativePath = PathFragment.create("relative/path");
     assertEquals(workingDir.getRelative(relativePath),
                  workingDir.getRelative(relativePath));
 
-    PathFragment absolutePath = new PathFragment("/absolute/path");
+    PathFragment absolutePath = PathFragment.create("/absolute/path");
     assertEquals(fileSystem.getPath(absolutePath),
                  workingDir.getRelative(absolutePath));
   }
@@ -781,16 +782,16 @@
 
   @Test
   public void testStartsWithAnySuccess() throws Exception {
-    PathFragment a = new PathFragment("a");
+    PathFragment a = PathFragment.create("a");
     assertTrue(FileSystemUtils.startsWithAny(a,
-        Arrays.asList(new PathFragment("b"), new PathFragment("a"))));
+        Arrays.asList(PathFragment.create("b"), PathFragment.create("a"))));
   }
 
   @Test
   public void testStartsWithAnyNotFound() throws Exception {
-    PathFragment a = new PathFragment("a");
+    PathFragment a = PathFragment.create("a");
     assertFalse(FileSystemUtils.startsWithAny(a,
-        Arrays.asList(new PathFragment("b"), new PathFragment("c"))));
+        Arrays.asList(PathFragment.create("b"), PathFragment.create("c"))));
   }
 
   @Test
@@ -811,7 +812,7 @@
 
   @Test
   public void testEnsureSymbolicLinkDoesNotMakeUnnecessaryChanges() throws Exception {
-    PathFragment target = new PathFragment("/b");
+    PathFragment target = PathFragment.create("/b");
     Path file = fileSystem.getPath("/a");
     file.createSymbolicLink(target);
     long prevTimeMillis = clock.currentTimeMillis();
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/ModifiedFileSetTest.java b/src/test/java/com/google/devtools/build/lib/vfs/ModifiedFileSetTest.java
index 07eedbe..f3c5eb6 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/ModifiedFileSetTest.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/ModifiedFileSetTest.java
@@ -28,8 +28,8 @@
 
   @Test
   public void testHashCodeAndEqualsContract() throws Exception {
-    PathFragment fragA = new PathFragment("a");
-    PathFragment fragB = new PathFragment("b");
+    PathFragment fragA = PathFragment.create("a");
+    PathFragment fragB = PathFragment.create("b");
 
     ModifiedFileSet empty1 = ModifiedFileSet.NOTHING_MODIFIED;
     ModifiedFileSet empty2 = ModifiedFileSet.builder().build();
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentTest.java b/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentTest.java
index c4ac7c1..2e455cc 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentTest.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentTest.java
@@ -40,10 +40,13 @@
 public class PathFragmentTest {
   @Test
   public void testMergeFourPathsWithAbsolute() {
-    assertEquals(new PathFragment("x/y/z/a/b/c/d/e"),
-        new PathFragment(new PathFragment("x/y"), new PathFragment("z/a"),
-            new PathFragment("/b/c"), // absolute!
-            new PathFragment("d/e")));
+    assertEquals(
+        PathFragment.create("x/y/z/a/b/c/d/e"),
+        PathFragment.create(
+            PathFragment.create("x/y"),
+            PathFragment.create("z/a"),
+            PathFragment.create("/b/c"),
+            PathFragment.create("d/e")));
   }
 
   @Test
@@ -68,22 +71,22 @@
 
     new EqualsTester()
         .addEqualityGroup(
-            new PathFragment("../relative/path"),
-            new PathFragment("..").getRelative("relative").getRelative("path"),
-            new PathFragment('\0', false, new String[] {"..", "relative", "path"}),
-            new PathFragment(new File("../relative/path")))
-        .addEqualityGroup(new PathFragment("something/else"))
-        .addEqualityGroup(new PathFragment("/something/else"))
-        .addEqualityGroup(new PathFragment("/"), new PathFragment("//////"))
-        .addEqualityGroup(new PathFragment(""), PathFragment.EMPTY_FRAGMENT)
+            PathFragment.create("../relative/path"),
+            PathFragment.create("..").getRelative("relative").getRelative("path"),
+            PathFragment.createNoClone('\0', false, new String[] {"..", "relative", "path"}),
+            PathFragment.create(new File("../relative/path")))
+        .addEqualityGroup(PathFragment.create("something/else"))
+        .addEqualityGroup(PathFragment.create("/something/else"))
+        .addEqualityGroup(PathFragment.create("/"), PathFragment.create("//////"))
+        .addEqualityGroup(PathFragment.create(""), PathFragment.EMPTY_FRAGMENT)
         .addEqualityGroup(filesystem.getRootDirectory()) // A Path object.
         .testEquals();
   }
 
   @Test
   public void testHashCodeCache() {
-    PathFragment relativePath = new PathFragment("../relative/path");
-    PathFragment rootPath = new PathFragment("/");
+    PathFragment relativePath = PathFragment.create("../relative/path");
+    PathFragment rootPath = PathFragment.create("/");
 
     int oldResult = relativePath.hashCode();
     int rootResult = rootPath.hashCode();
@@ -92,19 +95,21 @@
   }
 
   private void checkRelativeTo(String path, String base) {
-    PathFragment relative = new PathFragment(path).relativeTo(base);
-    assertEquals(new PathFragment(path), new PathFragment(base).getRelative(relative).normalize());
+    PathFragment relative = PathFragment.create(path).relativeTo(base);
+    assertEquals(
+        PathFragment.create(path),
+        PathFragment.create(base).getRelative(relative).normalize());
   }
 
   @Test
   public void testRelativeTo() {
-    assertPath("bar/baz", new PathFragment("foo/bar/baz").relativeTo("foo"));
-    assertPath("bar/baz", new PathFragment("/foo/bar/baz").relativeTo("/foo"));
-    assertPath("baz", new PathFragment("foo/bar/baz").relativeTo("foo/bar"));
-    assertPath("baz", new PathFragment("/foo/bar/baz").relativeTo("/foo/bar"));
-    assertPath("foo", new PathFragment("/foo").relativeTo("/"));
-    assertPath("foo", new PathFragment("foo").relativeTo(""));
-    assertPath("foo/bar", new PathFragment("foo/bar").relativeTo(""));
+    assertPath("bar/baz", PathFragment.create("foo/bar/baz").relativeTo("foo"));
+    assertPath("bar/baz", PathFragment.create("/foo/bar/baz").relativeTo("/foo"));
+    assertPath("baz", PathFragment.create("foo/bar/baz").relativeTo("foo/bar"));
+    assertPath("baz", PathFragment.create("/foo/bar/baz").relativeTo("/foo/bar"));
+    assertPath("foo", PathFragment.create("/foo").relativeTo("/"));
+    assertPath("foo", PathFragment.create("foo").relativeTo(""));
+    assertPath("foo/bar", PathFragment.create("foo/bar").relativeTo(""));
 
     checkRelativeTo("foo/bar/baz", "foo");
     checkRelativeTo("/foo/bar/baz", "/foo");
@@ -117,26 +122,26 @@
 
   @Test
   public void testIsAbsolute() {
-    assertTrue(new PathFragment("/absolute/test").isAbsolute());
-    assertFalse(new PathFragment("relative/test").isAbsolute());
-    assertTrue(new PathFragment(new File("/absolute/test")).isAbsolute());
-    assertFalse(new PathFragment(new File("relative/test")).isAbsolute());
+    assertTrue(PathFragment.create("/absolute/test").isAbsolute());
+    assertFalse(PathFragment.create("relative/test").isAbsolute());
+    assertTrue(PathFragment.create(new File("/absolute/test")).isAbsolute());
+    assertFalse(PathFragment.create(new File("relative/test")).isAbsolute());
   }
 
   @Test
   public void testIsNormalized() {
-    assertTrue(new PathFragment("/absolute/path").isNormalized());
-    assertTrue(new PathFragment("some//path").isNormalized());
-    assertFalse(new PathFragment("some/./path").isNormalized());
-    assertFalse(new PathFragment("../some/path").isNormalized());
-    assertFalse(new PathFragment("some/other/../path").isNormalized());
-    assertTrue(new PathFragment("some/other//tricky..path..").isNormalized());
-    assertTrue(new PathFragment("/some/other//tricky..path..").isNormalized());
+    assertTrue(PathFragment.create("/absolute/path").isNormalized());
+    assertTrue(PathFragment.create("some//path").isNormalized());
+    assertFalse(PathFragment.create("some/./path").isNormalized());
+    assertFalse(PathFragment.create("../some/path").isNormalized());
+    assertFalse(PathFragment.create("some/other/../path").isNormalized());
+    assertTrue(PathFragment.create("some/other//tricky..path..").isNormalized());
+    assertTrue(PathFragment.create("/some/other//tricky..path..").isNormalized());
   }
 
   @Test
   public void testRootNodeReturnsRootString() {
-    PathFragment rootFragment = new PathFragment("/");
+    PathFragment rootFragment = PathFragment.create("/");
     assertEquals("/", rootFragment.getPathString());
   }
 
@@ -144,27 +149,27 @@
   public void testGetPathFragmentDoesNotNormalize() {
     String nonCanonicalPath = "/a/weird/noncanonical/../path/.";
     assertEquals(nonCanonicalPath,
-        new PathFragment(nonCanonicalPath).getPathString());
+        PathFragment.create(nonCanonicalPath).getPathString());
   }
 
   @Test
   public void testGetRelative() {
-    assertEquals("a/b", new PathFragment("a").getRelative("b").getPathString());
-    assertEquals("a/b/c/d", new PathFragment("a/b").getRelative("c/d").getPathString());
-    assertEquals("/a/b", new PathFragment("c/d").getRelative("/a/b").getPathString());
-    assertEquals("a", new PathFragment("a").getRelative("").getPathString());
-    assertEquals("/", new PathFragment("/").getRelative("").getPathString());
+    assertEquals("a/b", PathFragment.create("a").getRelative("b").getPathString());
+    assertEquals("a/b/c/d", PathFragment.create("a/b").getRelative("c/d").getPathString());
+    assertEquals("/a/b", PathFragment.create("c/d").getRelative("/a/b").getPathString());
+    assertEquals("a", PathFragment.create("a").getRelative("").getPathString());
+    assertEquals("/", PathFragment.create("/").getRelative("").getPathString());
   }
 
   @Test
   public void testGetChildWorks() {
-    PathFragment pf = new PathFragment("../some/path");
-    assertEquals(new PathFragment("../some/path/hi"), pf.getChild("hi"));
+    PathFragment pf = PathFragment.create("../some/path");
+    assertEquals(PathFragment.create("../some/path/hi"), pf.getChild("hi"));
   }
 
   @Test
   public void testGetChildRejectsInvalidBaseNames() {
-    PathFragment pf = new PathFragment("../some/path");
+    PathFragment pf = PathFragment.create("../some/path");
     assertGetChildFails(pf, ".");
     assertGetChildFails(pf, "..");
     assertGetChildFails(pf, "x/y");
@@ -182,8 +187,14 @@
 
   // Tests after here test the canonicalization
   private void assertRegular(String expected, String actual) {
-    assertEquals(expected, new PathFragment(actual).getPathString()); // compare string forms
-    assertEquals(new PathFragment(expected), new PathFragment(actual)); // compare fragment forms
+    // compare string forms
+    assertEquals(
+        expected,
+        PathFragment.create(actual).getPathString());
+    // compare fragment forms
+    assertEquals(
+        PathFragment.create(expected),
+        PathFragment.create(actual));
   }
 
   @Test
@@ -218,19 +229,19 @@
 
   @Test
   public void testGetParentDirectory() {
-    PathFragment fooBarWiz = new PathFragment("foo/bar/wiz");
-    PathFragment fooBar = new PathFragment("foo/bar");
-    PathFragment foo = new PathFragment("foo");
-    PathFragment empty = new PathFragment("");
+    PathFragment fooBarWiz = PathFragment.create("foo/bar/wiz");
+    PathFragment fooBar = PathFragment.create("foo/bar");
+    PathFragment foo = PathFragment.create("foo");
+    PathFragment empty = PathFragment.create("");
     assertEquals(fooBar, fooBarWiz.getParentDirectory());
     assertEquals(foo, fooBar.getParentDirectory());
     assertEquals(empty, foo.getParentDirectory());
     assertNull(empty.getParentDirectory());
 
-    PathFragment fooBarWizAbs = new PathFragment("/foo/bar/wiz");
-    PathFragment fooBarAbs = new PathFragment("/foo/bar");
-    PathFragment fooAbs = new PathFragment("/foo");
-    PathFragment rootAbs = new PathFragment("/");
+    PathFragment fooBarWizAbs = PathFragment.create("/foo/bar/wiz");
+    PathFragment fooBarAbs = PathFragment.create("/foo/bar");
+    PathFragment fooAbs = PathFragment.create("/foo");
+    PathFragment rootAbs = PathFragment.create("/");
     assertEquals(fooBarAbs, fooBarWizAbs.getParentDirectory());
     assertEquals(fooAbs, fooBarAbs.getParentDirectory());
     assertEquals(rootAbs, fooAbs.getParentDirectory());
@@ -238,60 +249,60 @@
 
     // Note, this is surprising but correct behavior:
     assertEquals(fooBarAbs,
-                 new PathFragment("/foo/bar/..").getParentDirectory());
+                 PathFragment.create("/foo/bar/..").getParentDirectory());
   }
 
   @Test
   public void testSegmentsCount() {
-    assertEquals(2, new PathFragment("foo/bar").segmentCount());
-    assertEquals(2, new PathFragment("/foo/bar").segmentCount());
-    assertEquals(2, new PathFragment("foo//bar").segmentCount());
-    assertEquals(2, new PathFragment("/foo//bar").segmentCount());
-    assertEquals(1, new PathFragment("foo/").segmentCount());
-    assertEquals(1, new PathFragment("/foo/").segmentCount());
-    assertEquals(1, new PathFragment("foo").segmentCount());
-    assertEquals(1, new PathFragment("/foo").segmentCount());
-    assertEquals(0, new PathFragment("/").segmentCount());
-    assertEquals(0, new PathFragment("").segmentCount());
+    assertEquals(2, PathFragment.create("foo/bar").segmentCount());
+    assertEquals(2, PathFragment.create("/foo/bar").segmentCount());
+    assertEquals(2, PathFragment.create("foo//bar").segmentCount());
+    assertEquals(2, PathFragment.create("/foo//bar").segmentCount());
+    assertEquals(1, PathFragment.create("foo/").segmentCount());
+    assertEquals(1, PathFragment.create("/foo/").segmentCount());
+    assertEquals(1, PathFragment.create("foo").segmentCount());
+    assertEquals(1, PathFragment.create("/foo").segmentCount());
+    assertEquals(0, PathFragment.create("/").segmentCount());
+    assertEquals(0, PathFragment.create("").segmentCount());
   }
 
 
   @Test
   public void testGetSegment() {
-    assertEquals("foo", new PathFragment("foo/bar").getSegment(0));
-    assertEquals("bar", new PathFragment("foo/bar").getSegment(1));
-    assertEquals("foo", new PathFragment("/foo/bar").getSegment(0));
-    assertEquals("bar", new PathFragment("/foo/bar").getSegment(1));
-    assertEquals("foo", new PathFragment("foo/").getSegment(0));
-    assertEquals("foo", new PathFragment("/foo/").getSegment(0));
-    assertEquals("foo", new PathFragment("foo").getSegment(0));
-    assertEquals("foo", new PathFragment("/foo").getSegment(0));
+    assertEquals("foo", PathFragment.create("foo/bar").getSegment(0));
+    assertEquals("bar", PathFragment.create("foo/bar").getSegment(1));
+    assertEquals("foo", PathFragment.create("/foo/bar").getSegment(0));
+    assertEquals("bar", PathFragment.create("/foo/bar").getSegment(1));
+    assertEquals("foo", PathFragment.create("foo/").getSegment(0));
+    assertEquals("foo", PathFragment.create("/foo/").getSegment(0));
+    assertEquals("foo", PathFragment.create("foo").getSegment(0));
+    assertEquals("foo", PathFragment.create("/foo").getSegment(0));
   }
 
   @Test
   public void testBasename() throws Exception {
-    assertEquals("bar", new PathFragment("foo/bar").getBaseName());
-    assertEquals("bar", new PathFragment("/foo/bar").getBaseName());
-    assertEquals("foo", new PathFragment("foo/").getBaseName());
-    assertEquals("foo", new PathFragment("/foo/").getBaseName());
-    assertEquals("foo", new PathFragment("foo").getBaseName());
-    assertEquals("foo", new PathFragment("/foo").getBaseName());
-    assertThat(new PathFragment("/").getBaseName()).isEmpty();
-    assertThat(new PathFragment("").getBaseName()).isEmpty();
+    assertEquals("bar", PathFragment.create("foo/bar").getBaseName());
+    assertEquals("bar", PathFragment.create("/foo/bar").getBaseName());
+    assertEquals("foo", PathFragment.create("foo/").getBaseName());
+    assertEquals("foo", PathFragment.create("/foo/").getBaseName());
+    assertEquals("foo", PathFragment.create("foo").getBaseName());
+    assertEquals("foo", PathFragment.create("/foo").getBaseName());
+    assertThat(PathFragment.create("/").getBaseName()).isEmpty();
+    assertThat(PathFragment.create("").getBaseName()).isEmpty();
   }
 
   @Test
   public void testFileExtension() throws Exception {
-    assertThat(new PathFragment("foo.bar").getFileExtension()).isEqualTo("bar");
-    assertThat(new PathFragment("foo.barr").getFileExtension()).isEqualTo("barr");
-    assertThat(new PathFragment("foo.b").getFileExtension()).isEqualTo("b");
-    assertThat(new PathFragment("foo.").getFileExtension()).isEmpty();
-    assertThat(new PathFragment("foo").getFileExtension()).isEmpty();
-    assertThat(new PathFragment(".").getFileExtension()).isEmpty();
-    assertThat(new PathFragment("").getFileExtension()).isEmpty();
-    assertThat(new PathFragment("foo/bar.baz").getFileExtension()).isEqualTo("baz");
-    assertThat(new PathFragment("foo.bar.baz").getFileExtension()).isEqualTo("baz");
-    assertThat(new PathFragment("foo.bar/baz").getFileExtension()).isEmpty();
+    assertThat(PathFragment.create("foo.bar").getFileExtension()).isEqualTo("bar");
+    assertThat(PathFragment.create("foo.barr").getFileExtension()).isEqualTo("barr");
+    assertThat(PathFragment.create("foo.b").getFileExtension()).isEqualTo("b");
+    assertThat(PathFragment.create("foo.").getFileExtension()).isEmpty();
+    assertThat(PathFragment.create("foo").getFileExtension()).isEmpty();
+    assertThat(PathFragment.create(".").getFileExtension()).isEmpty();
+    assertThat(PathFragment.create("").getFileExtension()).isEmpty();
+    assertThat(PathFragment.create("foo/bar.baz").getFileExtension()).isEqualTo("baz");
+    assertThat(PathFragment.create("foo.bar.baz").getFileExtension()).isEqualTo("baz");
+    assertThat(PathFragment.create("foo.bar/baz").getFileExtension()).isEmpty();
   }
 
   private static void assertPath(String expected, PathFragment actual) {
@@ -300,66 +311,66 @@
 
   @Test
   public void testReplaceName() throws Exception {
-    assertPath("foo/baz", new PathFragment("foo/bar").replaceName("baz"));
-    assertPath("/foo/baz", new PathFragment("/foo/bar").replaceName("baz"));
-    assertPath("foo", new PathFragment("foo/bar").replaceName(""));
-    assertPath("baz", new PathFragment("foo/").replaceName("baz"));
-    assertPath("/baz", new PathFragment("/foo/").replaceName("baz"));
-    assertPath("baz", new PathFragment("foo").replaceName("baz"));
-    assertPath("/baz", new PathFragment("/foo").replaceName("baz"));
-    assertNull(new PathFragment("/").replaceName("baz"));
-    assertNull(new PathFragment("/").replaceName(""));
-    assertNull(new PathFragment("").replaceName("baz"));
-    assertNull(new PathFragment("").replaceName(""));
+    assertPath("foo/baz", PathFragment.create("foo/bar").replaceName("baz"));
+    assertPath("/foo/baz", PathFragment.create("/foo/bar").replaceName("baz"));
+    assertPath("foo", PathFragment.create("foo/bar").replaceName(""));
+    assertPath("baz", PathFragment.create("foo/").replaceName("baz"));
+    assertPath("/baz", PathFragment.create("/foo/").replaceName("baz"));
+    assertPath("baz", PathFragment.create("foo").replaceName("baz"));
+    assertPath("/baz", PathFragment.create("/foo").replaceName("baz"));
+    assertNull(PathFragment.create("/").replaceName("baz"));
+    assertNull(PathFragment.create("/").replaceName(""));
+    assertNull(PathFragment.create("").replaceName("baz"));
+    assertNull(PathFragment.create("").replaceName(""));
 
-    assertPath("foo/bar/baz", new PathFragment("foo/bar").replaceName("bar/baz"));
-    assertPath("foo/bar/baz", new PathFragment("foo/bar").replaceName("bar/baz/"));
+    assertPath("foo/bar/baz", PathFragment.create("foo/bar").replaceName("bar/baz"));
+    assertPath("foo/bar/baz", PathFragment.create("foo/bar").replaceName("bar/baz/"));
 
     // Absolute path arguments will clobber the original path.
-    assertPath("/absolute", new PathFragment("foo/bar").replaceName("/absolute"));
-    assertPath("/", new PathFragment("foo/bar").replaceName("/"));
+    assertPath("/absolute", PathFragment.create("foo/bar").replaceName("/absolute"));
+    assertPath("/", PathFragment.create("foo/bar").replaceName("/"));
   }
   @Test
   public void testSubFragment() throws Exception {
     assertPath("/foo/bar/baz",
-        new PathFragment("/foo/bar/baz").subFragment(0, 3));
+        PathFragment.create("/foo/bar/baz").subFragment(0, 3));
     assertPath("foo/bar/baz",
-        new PathFragment("foo/bar/baz").subFragment(0, 3));
+        PathFragment.create("foo/bar/baz").subFragment(0, 3));
     assertPath("/foo/bar",
-               new PathFragment("/foo/bar/baz").subFragment(0, 2));
+               PathFragment.create("/foo/bar/baz").subFragment(0, 2));
     assertPath("bar/baz",
-               new PathFragment("/foo/bar/baz").subFragment(1, 3));
+               PathFragment.create("/foo/bar/baz").subFragment(1, 3));
     assertPath("/foo",
-               new PathFragment("/foo/bar/baz").subFragment(0, 1));
+               PathFragment.create("/foo/bar/baz").subFragment(0, 1));
     assertPath("bar",
-               new PathFragment("/foo/bar/baz").subFragment(1, 2));
-    assertPath("baz", new PathFragment("/foo/bar/baz").subFragment(2, 3));
-    assertPath("/", new PathFragment("/foo/bar/baz").subFragment(0, 0));
-    assertPath("", new PathFragment("foo/bar/baz").subFragment(0, 0));
-    assertPath("", new PathFragment("foo/bar/baz").subFragment(1, 1));
+               PathFragment.create("/foo/bar/baz").subFragment(1, 2));
+    assertPath("baz", PathFragment.create("/foo/bar/baz").subFragment(2, 3));
+    assertPath("/", PathFragment.create("/foo/bar/baz").subFragment(0, 0));
+    assertPath("", PathFragment.create("foo/bar/baz").subFragment(0, 0));
+    assertPath("", PathFragment.create("foo/bar/baz").subFragment(1, 1));
     try {
-      fail("unexpectedly succeeded: " + new PathFragment("foo/bar/baz").subFragment(3, 2));
+      fail("unexpectedly succeeded: " + PathFragment.create("foo/bar/baz").subFragment(3, 2));
     } catch (IndexOutOfBoundsException e) { /* Expected. */ }
     try {
-      fail("unexpectedly succeeded: " + new PathFragment("foo/bar/baz").subFragment(4, 4));
+      fail("unexpectedly succeeded: " + PathFragment.create("foo/bar/baz").subFragment(4, 4));
     } catch (IndexOutOfBoundsException e) { /* Expected. */ }
   }
 
   @Test
   public void testStartsWith() {
-    PathFragment foobar = new PathFragment("/foo/bar");
-    PathFragment foobarRelative = new PathFragment("foo/bar");
+    PathFragment foobar = PathFragment.create("/foo/bar");
+    PathFragment foobarRelative = PathFragment.create("foo/bar");
 
     // (path, prefix) => true
     assertTrue(foobar.startsWith(foobar));
-    assertTrue(foobar.startsWith(new PathFragment("/")));
-    assertTrue(foobar.startsWith(new PathFragment("/foo")));
-    assertTrue(foobar.startsWith(new PathFragment("/foo/")));
-    assertTrue(foobar.startsWith(new PathFragment("/foo/bar/")));  // Includes trailing slash.
+    assertTrue(foobar.startsWith(PathFragment.create("/")));
+    assertTrue(foobar.startsWith(PathFragment.create("/foo")));
+    assertTrue(foobar.startsWith(PathFragment.create("/foo/")));
+    assertTrue(foobar.startsWith(PathFragment.create("/foo/bar/")));  // Includes trailing slash.
 
     // (prefix, path) => false
-    assertFalse(new PathFragment("/foo").startsWith(foobar));
-    assertFalse(new PathFragment("/").startsWith(foobar));
+    assertFalse(PathFragment.create("/foo").startsWith(foobar));
+    assertFalse(PathFragment.create("/").startsWith(foobar));
 
     // (absolute, relative) => false
     assertFalse(foobar.startsWith(foobarRelative));
@@ -367,40 +378,40 @@
 
     // (relative path, relative prefix) => true
     assertTrue(foobarRelative.startsWith(foobarRelative));
-    assertTrue(foobarRelative.startsWith(new PathFragment("foo")));
-    assertTrue(foobarRelative.startsWith(new PathFragment("")));
+    assertTrue(foobarRelative.startsWith(PathFragment.create("foo")));
+    assertTrue(foobarRelative.startsWith(PathFragment.create("")));
 
     // (path, sibling) => false
-    assertFalse(new PathFragment("/foo/wiz").startsWith(foobar));
-    assertFalse(foobar.startsWith(new PathFragment("/foo/wiz")));
+    assertFalse(PathFragment.create("/foo/wiz").startsWith(foobar));
+    assertFalse(foobar.startsWith(PathFragment.create("/foo/wiz")));
 
     // Does not normalize.
-    PathFragment foodotbar = new PathFragment("foo/./bar");
+    PathFragment foodotbar = PathFragment.create("foo/./bar");
     assertTrue(foodotbar.startsWith(foodotbar));
-    assertTrue(foodotbar.startsWith(new PathFragment("foo/.")));
-    assertTrue(foodotbar.startsWith(new PathFragment("foo/./")));
-    assertTrue(foodotbar.startsWith(new PathFragment("foo/./bar")));
-    assertFalse(foodotbar.startsWith(new PathFragment("foo/bar")));
+    assertTrue(foodotbar.startsWith(PathFragment.create("foo/.")));
+    assertTrue(foodotbar.startsWith(PathFragment.create("foo/./")));
+    assertTrue(foodotbar.startsWith(PathFragment.create("foo/./bar")));
+    assertFalse(foodotbar.startsWith(PathFragment.create("foo/bar")));
   }
 
   @Test
   public void testFilterPathsStartingWith() {
     // Retains everything:
     ImmutableSet<PathFragment> allUnderA = toPathsSet("a/b", "a/c", "a/d");
-    assertThat(PathFragment.filterPathsStartingWith(allUnderA, new PathFragment("a")))
+    assertThat(PathFragment.filterPathsStartingWith(allUnderA, PathFragment.create("a")))
         .containsExactlyElementsIn(allUnderA);
 
     // Retains some but not others:
     ImmutableSet<PathFragment> mixed = toPathsSet("a/b", "a/c", "b/c");
     assertThat(PathFragment.filterPathsStartingWith(mixed,
-        new PathFragment("a"))).containsExactlyElementsIn(toPathsSet("a/b", "a/c"));
+        PathFragment.create("a"))).containsExactlyElementsIn(toPathsSet("a/b", "a/c"));
 
     // Retains none:
-    assertThat(PathFragment.filterPathsStartingWith(allUnderA, new PathFragment("b"))).isEmpty();
+    assertThat(PathFragment.filterPathsStartingWith(allUnderA, PathFragment.create("b"))).isEmpty();
 
     // Retains paths equal to the startingWithPath:
     assertThat(PathFragment.filterPathsStartingWith(toPathsSet("a"),
-        new PathFragment("a"))).containsExactlyElementsIn(toPathsSet("a"));
+        PathFragment.create("a"))).containsExactlyElementsIn(toPathsSet("a"));
 
     // Retains everything when startingWithPath is the empty fragment:
     assertThat(PathFragment.filterPathsStartingWith(mixed, PathFragment.EMPTY_FRAGMENT))
@@ -408,23 +419,23 @@
 
     // Supports multi-segment startingWithPaths:
     assertThat(PathFragment.filterPathsStartingWith(toPathsSet("a/b/c", "a/b/d", "a/c/d"),
-        new PathFragment("a/b"))).containsExactlyElementsIn(toPathsSet("a/b/c", "a/b/d"));
+        PathFragment.create("a/b"))).containsExactlyElementsIn(toPathsSet("a/b/c", "a/b/d"));
   }
 
   @Test
   public void testCheckAllPathsStartWithButAreNotEqualTo() {
     // Check passes:
     PathFragment.checkAllPathsAreUnder(toPathsSet("a/b", "a/c"),
-        new PathFragment("a"));
+        PathFragment.create("a"));
 
     // Check trivially passes:
     PathFragment.checkAllPathsAreUnder(ImmutableList.<PathFragment>of(),
-        new PathFragment("a"));
+        PathFragment.create("a"));
 
     // Check fails when some path does not start with startingWithPath:
     try {
       PathFragment.checkAllPathsAreUnder(toPathsSet("a/b", "b/c"),
-          new PathFragment("a"));
+          PathFragment.create("a"));
       fail();
     } catch (IllegalArgumentException expected) {
     }
@@ -432,7 +443,7 @@
     // Check fails when some path is equal to startingWithPath:
     try {
       PathFragment.checkAllPathsAreUnder(toPathsSet("a/b", "a"),
-          new PathFragment("a"));
+          PathFragment.create("a"));
       fail();
     } catch (IllegalArgumentException expected) {
     }
@@ -440,24 +451,24 @@
 
   @Test
   public void testEndsWith() {
-    PathFragment foobar = new PathFragment("/foo/bar");
-    PathFragment foobarRelative = new PathFragment("foo/bar");
+    PathFragment foobar = PathFragment.create("/foo/bar");
+    PathFragment foobarRelative = PathFragment.create("foo/bar");
 
     // (path, suffix) => true
     assertTrue(foobar.endsWith(foobar));
-    assertTrue(foobar.endsWith(new PathFragment("bar")));
-    assertTrue(foobar.endsWith(new PathFragment("foo/bar")));
-    assertTrue(foobar.endsWith(new PathFragment("/foo/bar")));
-    assertFalse(foobar.endsWith(new PathFragment("/bar")));
+    assertTrue(foobar.endsWith(PathFragment.create("bar")));
+    assertTrue(foobar.endsWith(PathFragment.create("foo/bar")));
+    assertTrue(foobar.endsWith(PathFragment.create("/foo/bar")));
+    assertFalse(foobar.endsWith(PathFragment.create("/bar")));
 
     // (prefix, path) => false
-    assertFalse(new PathFragment("/foo").endsWith(foobar));
-    assertFalse(new PathFragment("/").endsWith(foobar));
+    assertFalse(PathFragment.create("/foo").endsWith(foobar));
+    assertFalse(PathFragment.create("/").endsWith(foobar));
 
     // (suffix, path) => false
-    assertFalse(new PathFragment("/bar").endsWith(foobar));
-    assertFalse(new PathFragment("bar").endsWith(foobar));
-    assertFalse(new PathFragment("").endsWith(foobar));
+    assertFalse(PathFragment.create("/bar").endsWith(foobar));
+    assertFalse(PathFragment.create("bar").endsWith(foobar));
+    assertFalse(PathFragment.create("").endsWith(foobar));
 
     // (absolute, relative) => true
     assertTrue(foobar.endsWith(foobarRelative));
@@ -467,18 +478,18 @@
 
     // (relative path, relative prefix) => true
     assertTrue(foobarRelative.endsWith(foobarRelative));
-    assertTrue(foobarRelative.endsWith(new PathFragment("bar")));
-    assertTrue(foobarRelative.endsWith(new PathFragment("")));
+    assertTrue(foobarRelative.endsWith(PathFragment.create("bar")));
+    assertTrue(foobarRelative.endsWith(PathFragment.create("")));
 
     // (path, sibling) => false
-    assertFalse(new PathFragment("/foo/wiz").endsWith(foobar));
-    assertFalse(foobar.endsWith(new PathFragment("/foo/wiz")));
+    assertFalse(PathFragment.create("/foo/wiz").endsWith(foobar));
+    assertFalse(foobar.endsWith(PathFragment.create("/foo/wiz")));
   }
 
   static List<PathFragment> toPaths(List<String> strs) {
     List<PathFragment> paths = Lists.newArrayList();
     for (String s : strs) {
-      paths.add(new PathFragment(s));
+      paths.add(PathFragment.create(s));
     }
     return paths;
   }
@@ -486,7 +497,7 @@
   static ImmutableSet<PathFragment> toPathsSet(String... strs) {
     ImmutableSet.Builder<PathFragment> builder = ImmutableSet.builder();
     for (String str : strs) {
-      builder.add(new PathFragment(str));
+      builder.add(PathFragment.create(str));
     }
     return builder.build();
   }
@@ -528,24 +539,24 @@
 
   @Test
   public void testGetSafePathString() {
-    assertEquals("/", new PathFragment("/").getSafePathString());
-    assertEquals("/abc", new PathFragment("/abc").getSafePathString());
-    assertEquals(".", new PathFragment("").getSafePathString());
+    assertEquals("/", PathFragment.create("/").getSafePathString());
+    assertEquals("/abc", PathFragment.create("/abc").getSafePathString());
+    assertEquals(".", PathFragment.create("").getSafePathString());
     assertEquals(".", PathFragment.EMPTY_FRAGMENT.getSafePathString());
-    assertEquals("abc/def", new PathFragment("abc/def").getSafePathString());
+    assertEquals("abc/def", PathFragment.create("abc/def").getSafePathString());
   }
 
   @Test
   public void testNormalize() {
-    assertEquals(new PathFragment("/a/b"), new PathFragment("/a/b").normalize());
-    assertEquals(new PathFragment("/a/b"), new PathFragment("/a/./b").normalize());
-    assertEquals(new PathFragment("/b"), new PathFragment("/a/../b").normalize());
-    assertEquals(new PathFragment("a/b"), new PathFragment("a/b").normalize());
-    assertEquals(new PathFragment("../b"), new PathFragment("a/../../b").normalize());
-    assertEquals(new PathFragment(".."), new PathFragment("a/../..").normalize());
-    assertEquals(new PathFragment("b"), new PathFragment("a/../b").normalize());
-    assertEquals(new PathFragment("a/b"), new PathFragment("a/b/../b").normalize());
-    assertEquals(new PathFragment("/.."), new PathFragment("/..").normalize());
+    assertEquals(PathFragment.create("/a/b"), PathFragment.create("/a/b").normalize());
+    assertEquals(PathFragment.create("/a/b"), PathFragment.create("/a/./b").normalize());
+    assertEquals(PathFragment.create("/b"), PathFragment.create("/a/../b").normalize());
+    assertEquals(PathFragment.create("a/b"), PathFragment.create("a/b").normalize());
+    assertEquals(PathFragment.create("../b"), PathFragment.create("a/../../b").normalize());
+    assertEquals(PathFragment.create(".."), PathFragment.create("a/../..").normalize());
+    assertEquals(PathFragment.create("b"), PathFragment.create("a/../b").normalize());
+    assertEquals(PathFragment.create("a/b"), PathFragment.create("a/b/../b").normalize());
+    assertEquals(PathFragment.create("/.."), PathFragment.create("/..").normalize());
   }
 
   @Test
@@ -564,7 +575,7 @@
   }
 
   private void checkSerialization(String pathFragmentString, int expectedSize) throws Exception {
-    PathFragment a = new PathFragment(pathFragmentString);
+    PathFragment a = PathFragment.create(pathFragmentString);
     byte[] sa = TestUtils.serializeObject(a);
     assertEquals(expectedSize, sa.length);
 
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentWindowsTest.java b/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentWindowsTest.java
index 9506202..d220809 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentWindowsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentWindowsTest.java
@@ -34,47 +34,47 @@
 
   @Test
   public void testWindowsSeparator() {
-    assertEquals("bar/baz", new PathFragment("bar\\baz").toString());
-    assertEquals("C:/bar/baz", new PathFragment("c:\\bar\\baz").toString());
+    assertEquals("bar/baz", PathFragment.create("bar\\baz").toString());
+    assertEquals("C:/bar/baz", PathFragment.create("c:\\bar\\baz").toString());
   }
 
   @Test
   public void testIsAbsoluteWindows() {
-    assertTrue(new PathFragment("C:/").isAbsolute());
-    assertTrue(new PathFragment("C:/").isAbsolute());
-    assertTrue(new PathFragment("C:/foo").isAbsolute());
-    assertTrue(new PathFragment("d:/foo/bar").isAbsolute());
+    assertTrue(PathFragment.create("C:/").isAbsolute());
+    assertTrue(PathFragment.create("C:/").isAbsolute());
+    assertTrue(PathFragment.create("C:/foo").isAbsolute());
+    assertTrue(PathFragment.create("d:/foo/bar").isAbsolute());
 
-    assertFalse(new PathFragment("*:/").isAbsolute());
+    assertFalse(PathFragment.create("*:/").isAbsolute());
 
     // C: is not an absolute path, it points to the current active directory on drive C:.
-    assertFalse(new PathFragment("C:").isAbsolute());
-    assertFalse(new PathFragment("C:foo").isAbsolute());
+    assertFalse(PathFragment.create("C:").isAbsolute());
+    assertFalse(PathFragment.create("C:foo").isAbsolute());
   }
 
   @Test
   public void testAbsoluteAndAbsoluteLookingPaths() {
-    PathFragment p1 = new PathFragment("/c");
+    PathFragment p1 = PathFragment.create("/c");
     assertThat(p1.isAbsolute()).isTrue();
     assertThat(p1.getDriveLetter()).isEqualTo('\0');
     assertThat(p1.getSegments()).containsExactly("c");
 
-    PathFragment p2 = new PathFragment("/c/");
+    PathFragment p2 = PathFragment.create("/c/");
     assertThat(p2.isAbsolute()).isTrue();
     assertThat(p2.getDriveLetter()).isEqualTo('\0');
     assertThat(p2.getSegments()).containsExactly("c");
 
-    PathFragment p3 = new PathFragment("C:/");
+    PathFragment p3 = PathFragment.create("C:/");
     assertThat(p3.isAbsolute()).isTrue();
     assertThat(p3.getDriveLetter()).isEqualTo('C');
     assertThat(p3.getSegments()).isEmpty();
 
-    PathFragment p4 = new PathFragment("C:");
+    PathFragment p4 = PathFragment.create("C:");
     assertThat(p4.isAbsolute()).isFalse();
     assertThat(p4.getDriveLetter()).isEqualTo('C');
     assertThat(p4.getSegments()).isEmpty();
 
-    PathFragment p5 = new PathFragment("/c:");
+    PathFragment p5 = PathFragment.create("/c:");
     assertThat(p5.isAbsolute()).isTrue();
     assertThat(p5.getDriveLetter()).isEqualTo('\0');
     assertThat(p5.getSegments()).containsExactly("c:");
@@ -90,39 +90,39 @@
 
   @Test
   public void testIsAbsoluteWindowsBackslash() {
-    assertTrue(new PathFragment(new File("C:\\blah")).isAbsolute());
-    assertTrue(new PathFragment(new File("C:\\")).isAbsolute());
-    assertTrue(new PathFragment(new File("\\blah")).isAbsolute());
-    assertTrue(new PathFragment(new File("\\")).isAbsolute());
+    assertTrue(PathFragment.create(new File("C:\\blah")).isAbsolute());
+    assertTrue(PathFragment.create(new File("C:\\")).isAbsolute());
+    assertTrue(PathFragment.create(new File("\\blah")).isAbsolute());
+    assertTrue(PathFragment.create(new File("\\")).isAbsolute());
   }
 
   @Test
   public void testIsNormalizedWindows() {
-    assertTrue(new PathFragment("C:/").isNormalized());
-    assertTrue(new PathFragment("C:/absolute/path").isNormalized());
-    assertFalse(new PathFragment("C:/absolute/./path").isNormalized());
-    assertFalse(new PathFragment("C:/absolute/../path").isNormalized());
+    assertTrue(PathFragment.create("C:/").isNormalized());
+    assertTrue(PathFragment.create("C:/absolute/path").isNormalized());
+    assertFalse(PathFragment.create("C:/absolute/./path").isNormalized());
+    assertFalse(PathFragment.create("C:/absolute/../path").isNormalized());
   }
 
   @Test
   public void testRootNodeReturnsRootStringWindows() {
-    PathFragment rootFragment = new PathFragment("C:/");
+    PathFragment rootFragment = PathFragment.create("C:/");
     assertEquals("C:/", rootFragment.getPathString());
   }
 
   @Test
   public void testGetRelativeWindows() {
-    assertEquals("C:/a/b", new PathFragment("C:/a").getRelative("b").getPathString());
-    assertEquals("C:/a/b/c/d", new PathFragment("C:/a/b").getRelative("c/d").getPathString());
-    assertEquals("C:/b", new PathFragment("C:/a").getRelative("C:/b").getPathString());
-    assertEquals("C:/c/d", new PathFragment("C:/a/b").getRelative("C:/c/d").getPathString());
-    assertEquals("C:/b", new PathFragment("a").getRelative("C:/b").getPathString());
-    assertEquals("C:/c/d", new PathFragment("a/b").getRelative("C:/c/d").getPathString());
+    assertEquals("C:/a/b", PathFragment.create("C:/a").getRelative("b").getPathString());
+    assertEquals("C:/a/b/c/d", PathFragment.create("C:/a/b").getRelative("c/d").getPathString());
+    assertEquals("C:/b", PathFragment.create("C:/a").getRelative("C:/b").getPathString());
+    assertEquals("C:/c/d", PathFragment.create("C:/a/b").getRelative("C:/c/d").getPathString());
+    assertEquals("C:/b", PathFragment.create("a").getRelative("C:/b").getPathString());
+    assertEquals("C:/c/d", PathFragment.create("a/b").getRelative("C:/c/d").getPathString());
   }
 
   private void assertGetRelative(String path, String relative, PathFragment expected)
       throws Exception {
-    PathFragment actual = new PathFragment(path).getRelative(relative);
+    PathFragment actual = PathFragment.create(path).getRelative(relative);
     assertThat(actual.getPathString()).isEqualTo(expected.getPathString());
     assertThat(actual).isEqualTo(expected);
     assertThat(actual.getDriveLetter()).isEqualTo(expected.getDriveLetter());
@@ -131,8 +131,8 @@
 
   private void assertRelativeTo(String path, String relativeTo, String... expectedPathSegments)
       throws Exception {
-    PathFragment expected = new PathFragment('\0', false, expectedPathSegments);
-    PathFragment actual = new PathFragment(path).relativeTo(relativeTo);
+    PathFragment expected = PathFragment.createNoClone('\0', false, expectedPathSegments);
+    PathFragment actual = PathFragment.create(path).relativeTo(relativeTo);
     assertThat(actual.getPathString()).isEqualTo(expected.getPathString());
     assertThat(actual).isEqualTo(expected);
     assertThat(actual.getDriveLetter()).isEqualTo(expected.getDriveLetter());
@@ -141,7 +141,7 @@
 
   private void assertCantComputeRelativeTo(String path, String relativeTo) throws Exception {
     try {
-      new PathFragment(path).relativeTo(relativeTo);
+      PathFragment.create(path).relativeTo(relativeTo);
       Assert.fail("expected failure");
     } catch (Exception e) {
       assertThat(e.getMessage()).contains("is not beneath");
@@ -149,7 +149,7 @@
   }
 
   private static PathFragment makePath(char drive, boolean absolute, String... segments) {
-    return new PathFragment(drive, absolute, segments);
+    return PathFragment.createNoClone(drive, absolute, segments);
   }
 
   @Test
@@ -193,14 +193,14 @@
 
   @Test
   public void testGetChildWorks() {
-    PathFragment pf = new PathFragment("../some/path");
-    assertEquals(new PathFragment("../some/path/hi"), pf.getChild("hi"));
+    PathFragment pf = PathFragment.create("../some/path");
+    assertEquals(PathFragment.create("../some/path/hi"), pf.getChild("hi"));
   }
 
   // Tests after here test the canonicalization
   private void assertRegular(String expected, String actual) {
-    PathFragment exp = new PathFragment(expected);
-    PathFragment act = new PathFragment(actual);
+    PathFragment exp = PathFragment.create(expected);
+    PathFragment act = PathFragment.create(actual);
     assertThat(exp.getPathString()).isEqualTo(expected);
     assertThat(act.getPathString()).isEqualTo(expected);
     assertThat(act).isEqualTo(exp);
@@ -233,18 +233,18 @@
     // information to the path itself.
     assertAllEqual(
         PathFragment.EMPTY_FRAGMENT,
-        new PathFragment("C:"),
-        new PathFragment("D:"),
-        new PathFragment('\0', false, new String[0]),
-        new PathFragment('C', false, new String[0]),
-        new PathFragment('D', false, new String[0]));
-    assertAllEqual(new PathFragment("/c"), new PathFragment("/c/"));
-    assertThat(new PathFragment("C:/")).isNotEqualTo(new PathFragment("/c"));
-    assertThat(new PathFragment("C:/foo")).isNotEqualTo(new PathFragment("/c/foo"));
+        PathFragment.create("C:"),
+        PathFragment.create("D:"),
+        PathFragment.createNoClone('\0', false, new String[0]),
+        PathFragment.createNoClone('C', false, new String[0]),
+        PathFragment.createNoClone('D', false, new String[0]));
+    assertAllEqual(PathFragment.create("/c"), PathFragment.create("/c/"));
+    assertThat(PathFragment.create("C:/")).isNotEqualTo(PathFragment.create("/c"));
+    assertThat(PathFragment.create("C:/foo")).isNotEqualTo(PathFragment.create("/c/foo"));
 
-    assertThat(new PathFragment("C:/")).isNotEqualTo(new PathFragment("C:"));
-    assertThat(new PathFragment("C:/").getPathString())
-        .isNotEqualTo(new PathFragment("C:").getPathString());
+    assertThat(PathFragment.create("C:/")).isNotEqualTo(PathFragment.create("C:"));
+    assertThat(PathFragment.create("C:/").getPathString())
+        .isNotEqualTo(PathFragment.create("C:").getPathString());
   }
 
   @Test
@@ -271,10 +271,10 @@
 
   @Test
   public void testGetParentDirectoryWindows() {
-    PathFragment fooBarWizAbs = new PathFragment("C:/foo/bar/wiz");
-    PathFragment fooBarAbs = new PathFragment("C:/foo/bar");
-    PathFragment fooAbs = new PathFragment("C:/foo");
-    PathFragment rootAbs = new PathFragment("C:/");
+    PathFragment fooBarWizAbs = PathFragment.create("C:/foo/bar/wiz");
+    PathFragment fooBarAbs = PathFragment.create("C:/foo/bar");
+    PathFragment fooAbs = PathFragment.create("C:/foo");
+    PathFragment rootAbs = PathFragment.create("C:/");
     assertEquals(fooBarAbs, fooBarWizAbs.getParentDirectory());
     assertEquals(fooAbs, fooBarAbs.getParentDirectory());
     assertEquals(rootAbs, fooAbs.getParentDirectory());
@@ -282,29 +282,29 @@
 
     // Note, this is suprising but correct behaviour:
     assertEquals(fooBarAbs,
-                 new PathFragment("C:/foo/bar/..").getParentDirectory());
+                 PathFragment.create("C:/foo/bar/..").getParentDirectory());
   }
 
   @Test
   public void testSegmentsCountWindows() {
-    assertEquals(1, new PathFragment("C:/foo").segmentCount());
-    assertEquals(0, new PathFragment("C:/").segmentCount());
+    assertEquals(1, PathFragment.create("C:/foo").segmentCount());
+    assertEquals(0, PathFragment.create("C:/").segmentCount());
   }
 
   @Test
   public void testGetSegmentWindows() {
-    assertEquals("foo", new PathFragment("C:/foo/bar").getSegment(0));
-    assertEquals("bar", new PathFragment("C:/foo/bar").getSegment(1));
-    assertEquals("foo", new PathFragment("C:/foo/").getSegment(0));
-    assertEquals("foo", new PathFragment("C:/foo").getSegment(0));
+    assertEquals("foo", PathFragment.create("C:/foo/bar").getSegment(0));
+    assertEquals("bar", PathFragment.create("C:/foo/bar").getSegment(1));
+    assertEquals("foo", PathFragment.create("C:/foo/").getSegment(0));
+    assertEquals("foo", PathFragment.create("C:/foo").getSegment(0));
   }
 
   @Test
   public void testBasenameWindows() throws Exception {
-    assertEquals("bar", new PathFragment("C:/foo/bar").getBaseName());
-    assertEquals("foo", new PathFragment("C:/foo").getBaseName());
+    assertEquals("bar", PathFragment.create("C:/foo/bar").getBaseName());
+    assertEquals("foo", PathFragment.create("C:/foo").getBaseName());
     // Never return the drive name as a basename.
-    assertThat(new PathFragment("C:/").getBaseName()).isEmpty();
+    assertThat(PathFragment.create("C:/").getBaseName()).isEmpty();
   }
 
   private static void assertPath(String expected, PathFragment actual) {
@@ -313,43 +313,43 @@
 
   @Test
   public void testReplaceNameWindows() throws Exception {
-    assertPath("C:/foo/baz", new PathFragment("C:/foo/bar").replaceName("baz"));
-    assertNull(new PathFragment("C:/").replaceName("baz"));
+    assertPath("C:/foo/baz", PathFragment.create("C:/foo/bar").replaceName("baz"));
+    assertNull(PathFragment.create("C:/").replaceName("baz"));
   }
 
   @Test
   public void testStartsWithWindows() {
-    assertTrue(new PathFragment("C:/foo/bar").startsWith(new PathFragment("C:/foo")));
-    assertTrue(new PathFragment("C:/foo/bar").startsWith(new PathFragment("C:/")));
-    assertTrue(new PathFragment("C:foo/bar").startsWith(new PathFragment("C:")));
-    assertTrue(new PathFragment("C:/").startsWith(new PathFragment("C:/")));
-    assertTrue(new PathFragment("C:").startsWith(new PathFragment("C:")));
+    assertTrue(PathFragment.create("C:/foo/bar").startsWith(PathFragment.create("C:/foo")));
+    assertTrue(PathFragment.create("C:/foo/bar").startsWith(PathFragment.create("C:/")));
+    assertTrue(PathFragment.create("C:foo/bar").startsWith(PathFragment.create("C:")));
+    assertTrue(PathFragment.create("C:/").startsWith(PathFragment.create("C:/")));
+    assertTrue(PathFragment.create("C:").startsWith(PathFragment.create("C:")));
 
     // The first path is absolute, the second is not.
-    assertFalse(new PathFragment("C:/foo/bar").startsWith(new PathFragment("C:")));
-    assertFalse(new PathFragment("C:/").startsWith(new PathFragment("C:")));
+    assertFalse(PathFragment.create("C:/foo/bar").startsWith(PathFragment.create("C:")));
+    assertFalse(PathFragment.create("C:/").startsWith(PathFragment.create("C:")));
   }
 
   @Test
   public void testEndsWithWindows() {
-    assertTrue(new PathFragment("C:/foo/bar").endsWith(new PathFragment("bar")));
-    assertTrue(new PathFragment("C:/foo/bar").endsWith(new PathFragment("foo/bar")));
-    assertTrue(new PathFragment("C:/foo/bar").endsWith(new PathFragment("C:/foo/bar")));
-    assertTrue(new PathFragment("C:/").endsWith(new PathFragment("C:/")));
+    assertTrue(PathFragment.create("C:/foo/bar").endsWith(PathFragment.create("bar")));
+    assertTrue(PathFragment.create("C:/foo/bar").endsWith(PathFragment.create("foo/bar")));
+    assertTrue(PathFragment.create("C:/foo/bar").endsWith(PathFragment.create("C:/foo/bar")));
+    assertTrue(PathFragment.create("C:/").endsWith(PathFragment.create("C:/")));
   }
 
   @Test
   public void testGetSafePathStringWindows() {
-    assertEquals("C:/", new PathFragment("C:/").getSafePathString());
-    assertEquals("C:/abc", new PathFragment("C:/abc").getSafePathString());
-    assertEquals("C:/abc/def", new PathFragment("C:/abc/def").getSafePathString());
+    assertEquals("C:/", PathFragment.create("C:/").getSafePathString());
+    assertEquals("C:/abc", PathFragment.create("C:/abc").getSafePathString());
+    assertEquals("C:/abc/def", PathFragment.create("C:/abc/def").getSafePathString());
   }
 
   @Test
   public void testNormalizeWindows() {
-    assertEquals(new PathFragment("C:/a/b"), new PathFragment("C:/a/b").normalize());
-    assertEquals(new PathFragment("C:/a/b"), new PathFragment("C:/a/./b").normalize());
-    assertEquals(new PathFragment("C:/b"), new PathFragment("C:/a/../b").normalize());
-    assertEquals(new PathFragment("C:/../b"), new PathFragment("C:/../b").normalize());
+    assertEquals(PathFragment.create("C:/a/b"), PathFragment.create("C:/a/b").normalize());
+    assertEquals(PathFragment.create("C:/a/b"), PathFragment.create("C:/a/./b").normalize());
+    assertEquals(PathFragment.create("C:/b"), PathFragment.create("C:/a/../b").normalize());
+    assertEquals(PathFragment.create("C:/../b"), PathFragment.create("C:/../b").normalize());
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/PathGetParentTest.java b/src/test/java/com/google/devtools/build/lib/vfs/PathGetParentTest.java
index 5e6224c..5681ba2 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/PathGetParentTest.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/PathGetParentTest.java
@@ -81,6 +81,6 @@
 
     // Under UNIX, inode(/tmp/wiz/..) == inode(/).  However getPath() does not
     // perform I/O, only string operations, so it disagrees:
-    assertEquals(tmp, tmp.getRelative(new PathFragment("wiz/..")));
+    assertEquals(tmp, tmp.getRelative(PathFragment.create("wiz/..")));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/PathTest.java b/src/test/java/com/google/devtools/build/lib/vfs/PathTest.java
index 1976f05..de1a47c 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/PathTest.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/PathTest.java
@@ -179,11 +179,11 @@
   public void testGetRelativeWithFragmentWorks() {
     Path dir = filesystem.getPath("/first/x");
     assertEquals("/first/x/y",
-                 dir.getRelative(new PathFragment("y")).toString());
+                 dir.getRelative(PathFragment.create("y")).toString());
     assertEquals("/first/x/x",
-                 dir.getRelative(new PathFragment("./x")).toString());
+                 dir.getRelative(PathFragment.create("./x")).toString());
     assertEquals("/first/y",
-                 dir.getRelative(new PathFragment("../y")).toString());
+                 dir.getRelative(PathFragment.create("../y")).toString());
 
   }
 
@@ -191,7 +191,7 @@
   public void testGetRelativeWithAbsoluteFragmentWorks() {
     Path root = filesystem.getPath("/first/x");
     assertEquals("/x/y",
-                 root.getRelative(new PathFragment("/x/y")).toString());
+                 root.getRelative(PathFragment.create("/x/y")).toString());
   }
 
   @Test
@@ -238,14 +238,14 @@
   @Test
   public void testSiblingNonEquivalenceFragment() {
     assertNotSame(
-        root.getRelative(new PathFragment("aSingleSegment")),
-        root.getRelative(new PathFragment("aDifferentSegment")));
+        root.getRelative(PathFragment.create("aSingleSegment")),
+        root.getRelative(PathFragment.create("aDifferentSegment")));
   }
 
   @Test
   public void testHashCodeStableAcrossGarbageCollections() {
     Path parent = filesystem.getPath("/a");
-    PathFragment childFragment = new PathFragment("b");
+    PathFragment childFragment = PathFragment.create("b");
     Path child = parent.getRelative(childFragment);
     WeakReference<Path> childRef = new WeakReference<>(child);
     int childHashCode1 = childRef.get().hashCode();
@@ -315,7 +315,7 @@
   }
 
   private void assertAsFragmentWorks(String expected) {
-    assertEquals(new PathFragment(expected), filesystem.getPath(expected).asFragment());
+    assertEquals(PathFragment.create(expected), filesystem.getPath(expected).asFragment());
   }
 
   private void assertGetRelativeWorks(String expected, String relative) {
@@ -324,7 +324,7 @@
   }
 
   private void assertRelativeToWorks(String expected, String relative, String original) {
-    assertEquals(new PathFragment(expected),
+    assertEquals(PathFragment.create(expected),
                  filesystem.getPath(relative).relativeTo(filesystem.getPath(original)));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/RootedPathTest.java b/src/test/java/com/google/devtools/build/lib/vfs/RootedPathTest.java
index 83a7211..7ad6531 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/RootedPathTest.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/RootedPathTest.java
@@ -40,12 +40,14 @@
   public void testEqualsAndHashCodeContract() throws Exception {
     Path pkgRoot1 = root.getRelative("pkgroot1");
     Path pkgRoot2 = root.getRelative("pkgroot2");
-    RootedPath rootedPathA1 = RootedPath.toRootedPath(pkgRoot1, new PathFragment("foo/bar"));
-    RootedPath rootedPathA2 = RootedPath.toRootedPath(pkgRoot1, new PathFragment("foo/bar"));
-    RootedPath absolutePath1 = RootedPath.toRootedPath(root, new PathFragment("pkgroot1/foo/bar"));
-    RootedPath rootedPathB1 = RootedPath.toRootedPath(pkgRoot2, new PathFragment("foo/bar"));
-    RootedPath rootedPathB2 = RootedPath.toRootedPath(pkgRoot2, new PathFragment("foo/bar"));
-    RootedPath absolutePath2 = RootedPath.toRootedPath(root, new PathFragment("pkgroot2/foo/bar"));
+    RootedPath rootedPathA1 = RootedPath.toRootedPath(pkgRoot1, PathFragment.create("foo/bar"));
+    RootedPath rootedPathA2 = RootedPath.toRootedPath(pkgRoot1, PathFragment.create("foo/bar"));
+    RootedPath absolutePath1 =
+        RootedPath.toRootedPath(root, PathFragment.create("pkgroot1/foo/bar"));
+    RootedPath rootedPathB1 = RootedPath.toRootedPath(pkgRoot2, PathFragment.create("foo/bar"));
+    RootedPath rootedPathB2 = RootedPath.toRootedPath(pkgRoot2, PathFragment.create("foo/bar"));
+    RootedPath absolutePath2 =
+        RootedPath.toRootedPath(root, PathFragment.create("pkgroot2/foo/bar"));
     new EqualsTester()
       .addEqualityGroup(rootedPathA1, rootedPathA2)
       .addEqualityGroup(rootedPathB1, rootedPathB2)
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/ScopeEscapableFileSystemTest.java b/src/test/java/com/google/devtools/build/lib/vfs/ScopeEscapableFileSystemTest.java
index f321ab9..cec1523 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/ScopeEscapableFileSystemTest.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/ScopeEscapableFileSystemTest.java
@@ -129,7 +129,7 @@
     }
   }
 
-  protected static final PathFragment SCOPE_ROOT = new PathFragment("/fs/root");
+  protected static final PathFragment SCOPE_ROOT = PathFragment.create("/fs/root");
 
   private Path fileLink;
   private PathFragment fileLinkTarget;
@@ -146,11 +146,11 @@
     }
 
     fileLink = testFS.getPath(SCOPE_ROOT.getRelative("link"));
-    fileLinkTarget = new PathFragment("/should/be/delegated/fileLinkTarget");
+    fileLinkTarget = PathFragment.create("/should/be/delegated/fileLinkTarget");
     testFS.createSymbolicLink(fileLink, fileLinkTarget);
 
     dirLink = testFS.getPath(SCOPE_ROOT.getRelative("dirlink"));
-    dirLinkTarget = new PathFragment("/should/be/delegated/dirLinkTarget");
+    dirLinkTarget = PathFragment.create("/should/be/delegated/dirLinkTarget");
     testFS.createSymbolicLink(dirLink, dirLinkTarget);
   }
 
@@ -605,7 +605,7 @@
     };
     scopedFS().setDelegator(delegator);
 
-    PathFragment newLinkTarget = new PathFragment("/something/else");
+    PathFragment newLinkTarget = PathFragment.create("/something/else");
     dirLink.getRelative("a").createSymbolicLink(newLinkTarget);
     assertEquals(dirLinkTarget.getRelative("a"), delegator.lastPath());
     assertSame(newLinkTarget, delegator.objectState());
@@ -623,7 +623,7 @@
     scopedFS().setDelegator(delegator);
 
     // Since we're not following the link, this shouldn't invoke delegation.
-    delegator.setState(new PathFragment("whatever"));
+    delegator.setState(PathFragment.create("whatever"));
     PathFragment p = fileLink.readSymbolicLink();
     assertNull(delegator.lastPath());
     assertNotSame(delegator.objectState(), p);
@@ -705,7 +705,7 @@
    */
   private void assertInScopeLink(String link, String target, TestDelegator d) throws IOException {
     Path l = testFS.getPath(SCOPE_ROOT.getRelative(link));
-    testFS.createSymbolicLink(l, new PathFragment(target));
+    testFS.createSymbolicLink(l, PathFragment.create(target));
     l.exists();
     assertNull(d.lastPath());
   }
@@ -717,7 +717,7 @@
   private void assertOutOfScopeLink(String link, String target, String expectedPath,
       TestDelegator d) throws IOException {
     Path l = testFS.getPath(SCOPE_ROOT.getRelative(link));
-    testFS.createSymbolicLink(l, new PathFragment(target));
+    testFS.createSymbolicLink(l, PathFragment.create(target));
     l.exists();
     assertEquals(expectedPath, d.lastPath().getPathString());
   }
@@ -768,7 +768,7 @@
 
     // Out-of-scope symlink that's not the final segment in a query.
     Path oDirLink = testFS.getPath(SCOPE_ROOT.getRelative("olinkdir"));
-    testFS.createSymbolicLink(oDirLink, new PathFragment("/some/other/dir"));
+    testFS.createSymbolicLink(oDirLink, PathFragment.create("/some/other/dir"));
     oDirLink.getRelative("file").exists();
     assertEquals("/some/other/dir/file", d.lastPath().getPathString());
   }
@@ -807,13 +807,13 @@
 
     // In-scope symlink that's not the final segment in a query.
     Path iDirLink = testFS.getPath(SCOPE_ROOT.getRelative("dir/dir2/ilinkdir"));
-    testFS.createSymbolicLink(iDirLink, new PathFragment("../../dir"));
+    testFS.createSymbolicLink(iDirLink, PathFragment.create("../../dir"));
     iDirLink.getRelative("file").exists();
     assertNull(d.lastPath());
 
     // Out-of-scope symlink that's not the final segment in a query.
     Path oDirLink = testFS.getPath(SCOPE_ROOT.getRelative("dir/dir2/olinkdir"));
-    testFS.createSymbolicLink(oDirLink, new PathFragment("../../../other/dir"));
+    testFS.createSymbolicLink(oDirLink, PathFragment.create("../../../other/dir"));
     oDirLink.getRelative("file").exists();
     assertEquals(chopScopeRoot(1) + "/other/dir/file", d.lastPath().getPathString());
   }
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/SymlinkAwareFileSystemTest.java b/src/test/java/com/google/devtools/build/lib/vfs/SymlinkAwareFileSystemTest.java
index 9f9480c..b048748 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/SymlinkAwareFileSystemTest.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/SymlinkAwareFileSystemTest.java
@@ -200,7 +200,7 @@
     };
     Path linkPath = absolutize("link");
     for (String linkTarget : linkTargets) {
-      PathFragment relative = new PathFragment(linkTarget);
+      PathFragment relative = PathFragment.create(linkTarget);
       linkPath.delete();
       createSymbolicLink(linkPath, relative);
       if (supportsSymlinks) {
@@ -246,7 +246,7 @@
   @Test
   public void testLinkToFragmentContainingLinkResolvesCorrectly() throws IOException {
     Path link1 = absolutize("link1");
-    PathFragment link1target = new PathFragment("link2/foo");
+    PathFragment link1target = PathFragment.create("link2/foo");
     Path link2 = absolutize("link2");
     Path link2target = xNonEmptyDirectory;
 
@@ -331,7 +331,7 @@
       String prefix = "./";
       while ((ancestor = ancestor.getParentDirectory()) != null) {
         xLinkToFile.delete();
-        createSymbolicLink(xLinkToFile, new PathFragment(prefix + xFile.relativeTo(ancestor)));
+        createSymbolicLink(xLinkToFile, PathFragment.create(prefix + xFile.relativeTo(ancestor)));
         assertEquals(xFile, xLinkToFile.resolveSymbolicLinks());
 
         prefix += "../";
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/UnionFileSystemTest.java b/src/test/java/com/google/devtools/build/lib/vfs/UnionFileSystemTest.java
index 50329d6..c1e7935 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/UnionFileSystemTest.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/UnionFileSystemTest.java
@@ -64,8 +64,8 @@
 
   private UnionFileSystem createDefaultUnionFileSystem(boolean readOnly) {
     return new UnionFileSystem(ImmutableMap.<PathFragment, FileSystem>of(
-        new PathFragment("/in"), inDelegate,
-        new PathFragment("/out"), outDelegate),
+        PathFragment.create("/in"), inDelegate,
+        PathFragment.create("/out"), outDelegate),
         defaultDelegate, readOnly);
   }
 
@@ -123,8 +123,8 @@
   @Test
   public void testPrefixDelegation() throws Exception {
     unionfs = new UnionFileSystem(ImmutableMap.<PathFragment, FileSystem>of(
-              new PathFragment("/foo"), inDelegate,
-              new PathFragment("/foo/bar"), outDelegate), defaultDelegate);
+              PathFragment.create("/foo"), inDelegate,
+              PathFragment.create("/foo/bar"), outDelegate), defaultDelegate);
 
     assertSame(inDelegate, unionfs.getDelegate(unionfs.getPath("/foo/foo.txt")));
     assertSame(outDelegate, unionfs.getDelegate(unionfs.getPath("/foo/bar/foo.txt")));
@@ -220,7 +220,7 @@
     outStream.close();
 
     Path outFoo = unionfs.getPath("/out/foo");
-    unionfs.createSymbolicLink(outFoo, new PathFragment("../in/bar.txt"));
+    unionfs.createSymbolicLink(outFoo, PathFragment.create("../in/bar.txt"));
     assertTrue(unionfs.stat(outFoo, false).isSymbolicLink());
 
     try {
@@ -253,8 +253,8 @@
   @Test
   public void testWithinDirectoryMapping() throws Exception {
     unionfs = new UnionFileSystem(ImmutableMap.<PathFragment, FileSystem>of(
-        new PathFragment("/fruit/a"), inDelegate,
-        new PathFragment("/fruit/b"), outDelegate), defaultDelegate);
+        PathFragment.create("/fruit/a"), inDelegate,
+        PathFragment.create("/fruit/b"), outDelegate), defaultDelegate);
     assertTrue(unionfs.createDirectory(unionfs.getPath("/fruit")));
     assertTrue(defaultDelegate.getPath("/fruit").isDirectory());
     assertTrue(inDelegate.getPath("/fruit").createDirectory());
@@ -309,7 +309,7 @@
   @Test
   public void testCreateParentsAcrossMapping() throws Exception {
     unionfs = new UnionFileSystem(ImmutableMap.<PathFragment, FileSystem>of(
-        new PathFragment("/out/dir"), outDelegate), defaultDelegate, false);
+        PathFragment.create("/out/dir"), outDelegate), defaultDelegate, false);
     Path outDir = unionfs.getPath("/out/dir/biz/bang");
     FileSystemUtils.createDirectoryAndParents(outDir);
     assertTrue(outDir.isDirectory());
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystemTest.java b/src/test/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystemTest.java
index 6544666..ee4dfe9 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystemTest.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystemTest.java
@@ -394,8 +394,8 @@
   public void testEloop() throws Exception {
     Path a = testFS.getPath("/a");
     Path b = testFS.getPath("/b");
-    a.createSymbolicLink(new PathFragment("b"));
-    b.createSymbolicLink(new PathFragment("a"));
+    a.createSymbolicLink(PathFragment.create("b"));
+    b.createSymbolicLink(PathFragment.create("a"));
     try {
       a.stat();
     } catch (IOException e) {
@@ -406,7 +406,7 @@
   @Test
   public void testEloopSelf() throws Exception {
     Path a = testFS.getPath("/a");
-    a.createSymbolicLink(new PathFragment("a"));
+    a.createSymbolicLink(PathFragment.create("a"));
     try {
       a.stat();
     } catch (IOException e) {