Refactor: remove unnecessary ImmutableXXX.copyOf()

It's often a code smell if a constructor makes an
immutable copy of its argument, because often
those arguments could easily be an immutable
collection.

In this CL I mark arguments of such ctors as
Immutable and let the caller make the copy that
the ctor used to.

This CL doesn't introduce any new copies, because
it merely moves the copy calls to the call sites
(where copying is needed at all).

PiperOrigin-RevId: 289612603
diff --git a/src/main/java/com/google/devtools/build/lib/exec/local/LocalEnvProvider.java b/src/main/java/com/google/devtools/build/lib/exec/local/LocalEnvProvider.java
index 7d5213a..ea65ee8 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/local/LocalEnvProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/exec/local/LocalEnvProvider.java
@@ -13,6 +13,7 @@
 // limitations under the License.
 package com.google.devtools.build.lib.exec.local;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.exec.BinTools;
 import com.google.devtools.build.lib.util.OS;
 import java.io.IOException;
@@ -51,6 +52,6 @@
    *     typically the "TMPDIR" environment variable in the Bazel client's environment, but if
    *     that's unavailable, the implementation may decide to use this {@code fallbackTmpDir}.
    */
-  Map<String, String> rewriteLocalEnv(
+  ImmutableMap<String, String> rewriteLocalEnv(
       Map<String, String> env, BinTools binTools, String fallbackTmpDir) throws IOException;
 }
diff --git a/src/main/java/com/google/devtools/build/lib/exec/local/LocalSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/exec/local/LocalSpawnRunner.java
index 6f7d428..3916de0 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/local/LocalSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/exec/local/LocalSpawnRunner.java
@@ -20,6 +20,8 @@
 
 import com.google.common.base.Joiner;
 import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.actions.ActionExecutionMetadata;
 import com.google.devtools.build.lib.actions.ActionInput;
 import com.google.devtools.build.lib.actions.Artifact;
@@ -36,6 +38,7 @@
 import com.google.devtools.build.lib.exec.BinTools;
 import com.google.devtools.build.lib.exec.RunfilesTreeUpdater;
 import com.google.devtools.build.lib.exec.SpawnRunner;
+import com.google.devtools.build.lib.exec.SpawnRunner.SpawnExecutionContext;
 import com.google.devtools.build.lib.profiler.Profiler;
 import com.google.devtools.build.lib.profiler.ProfilerTask;
 import com.google.devtools.build.lib.profiler.SilentCloseable;
@@ -338,7 +341,7 @@
       try {
         Path commandTmpDir = tmpDir.getRelative("work");
         commandTmpDir.createDirectory();
-        Map<String, String> environment =
+        ImmutableMap<String, String> environment =
             localEnvProvider.rewriteLocalEnv(
                 spawn.getEnvironment(), binTools, commandTmpDir.getPathString());
 
@@ -347,7 +350,7 @@
         subprocessBuilder.setStdout(outErr.getOutputPath().getPathFile());
         subprocessBuilder.setStderr(outErr.getErrorPath().getPathFile());
         subprocessBuilder.setEnv(environment);
-        List<String> args;
+        ImmutableList<String> args;
         if (useProcessWrapper) {
           // If the process wrapper is enabled, we use its timeout feature, which first interrupts
           // the subprocess and only kills it after a grace period so that the subprocess can output
@@ -361,7 +364,7 @@
             statisticsPath = tmpDir.getRelative("stats.out");
             commandLineBuilder.setStatisticsPath(statisticsPath);
           }
-          args = commandLineBuilder.build();
+          args = ImmutableList.copyOf(commandLineBuilder.build());
         } else {
           subprocessBuilder.setTimeoutMillis(context.getTimeout().toMillis());
           args = spawn.getArguments();
@@ -370,8 +373,9 @@
         // Command does. We sometimes get relative paths here, so we need to handle it.
         File argv0 = new File(args.get(0));
         if (!argv0.isAbsolute() && argv0.getParent() != null) {
-          args = new ArrayList<>(args);
-          args.set(0, new File(execRoot.getPathFile(), args.get(0)).getAbsolutePath());
+          List<String> newArgs = new ArrayList<>(args);
+          newArgs.set(0, new File(execRoot.getPathFile(), newArgs.get(0)).getAbsolutePath());
+          args = ImmutableList.copyOf(newArgs);
         }
         subprocessBuilder.setArgv(args);
 
diff --git a/src/main/java/com/google/devtools/build/lib/exec/local/PosixLocalEnvProvider.java b/src/main/java/com/google/devtools/build/lib/exec/local/PosixLocalEnvProvider.java
index 7fdea61..6fff2af 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/local/PosixLocalEnvProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/exec/local/PosixLocalEnvProvider.java
@@ -43,7 +43,7 @@
    * if that's empty or null, then by "/tmp".
    */
   @Override
-  public Map<String, String> rewriteLocalEnv(
+  public ImmutableMap<String, String> rewriteLocalEnv(
       Map<String, String> env, BinTools binTools, String fallbackTmpDir) {
     ImmutableMap.Builder<String, String> result = ImmutableMap.builder();
     result.putAll(Maps.filterKeys(env, k -> !k.equals("TMPDIR")));
diff --git a/src/main/java/com/google/devtools/build/lib/exec/local/WindowsLocalEnvProvider.java b/src/main/java/com/google/devtools/build/lib/exec/local/WindowsLocalEnvProvider.java
index a6465a4..9179e1f 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/local/WindowsLocalEnvProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/exec/local/WindowsLocalEnvProvider.java
@@ -49,7 +49,7 @@
    * <p>The values for TMP and TEMP will use backslashes as directory separators.
    */
   @Override
-  public Map<String, String> rewriteLocalEnv(
+  public ImmutableMap<String, String> rewriteLocalEnv(
       Map<String, String> env, BinTools binTools, String fallbackTmpDir) {
     ImmutableMap.Builder<String, String> result = ImmutableMap.builder();
     result.putAll(Maps.filterKeys(env, k -> !k.equals("TMP") && !k.equals("TEMP")));
diff --git a/src/main/java/com/google/devtools/build/lib/exec/local/XcodeLocalEnvProvider.java b/src/main/java/com/google/devtools/build/lib/exec/local/XcodeLocalEnvProvider.java
index f64291e..9e545bb 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/local/XcodeLocalEnvProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/exec/local/XcodeLocalEnvProvider.java
@@ -65,7 +65,7 @@
   }
 
   @Override
-  public Map<String, String> rewriteLocalEnv(
+  public ImmutableMap<String, String> rewriteLocalEnv(
       Map<String, String> env, BinTools binTools, String fallbackTmpDir) throws IOException {
     boolean containsXcodeVersion = env.containsKey(AppleConfiguration.XCODE_VERSION_ENV_NAME);
     boolean containsAppleSdkVersion =
diff --git a/src/main/java/com/google/devtools/build/lib/pkgcache/TargetParsingCompleteEvent.java b/src/main/java/com/google/devtools/build/lib/pkgcache/TargetParsingCompleteEvent.java
index 0028fd5..77ea664 100644
--- a/src/main/java/com/google/devtools/build/lib/pkgcache/TargetParsingCompleteEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/pkgcache/TargetParsingCompleteEvent.java
@@ -29,7 +29,6 @@
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.packages.TargetUtils;
 import java.util.Collection;
-import java.util.List;
 import javax.annotation.Nullable;
 
 /** This event is fired just after target pattern evaluation is completed. */
@@ -89,16 +88,16 @@
       Collection<Target> targets,
       Collection<Target> filteredTargets,
       Collection<Target> testFilteredTargets,
-      List<String> originalTargetPattern,
+      ImmutableList<String> originalTargetPattern,
       Collection<Target> expandedTargets,
-      List<String> failedTargetPatterns,
+      ImmutableList<String> failedTargetPatterns,
       ImmutableSetMultimap<String, Label> originalPatternsToLabels) {
     this.targets = asThinTargets(targets);
     this.filteredTargets = asThinTargets(filteredTargets);
     this.testFilteredTargets = asThinTargets(testFilteredTargets);
-    this.originalTargetPattern = ImmutableList.copyOf(originalTargetPattern);
+    this.originalTargetPattern = Preconditions.checkNotNull(originalTargetPattern);
     this.expandedTargets = asThinTargets(expandedTargets);
-    this.failedTargetPatterns = ImmutableList.copyOf(failedTargetPatterns);
+    this.failedTargetPatterns = Preconditions.checkNotNull(failedTargetPatterns);
     this.originalPatternsToLabels = originalPatternsToLabels;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
index 4622931..c1919bd 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
@@ -968,10 +968,10 @@
     final ImmutableList<Artifact> shardDexZips;
 
     private DexingOutput(
-        Artifact classesDexZip, Artifact javaResourceJar, Iterable<Artifact> shardDexZips) {
+        Artifact classesDexZip, Artifact javaResourceJar, ImmutableList<Artifact> shardDexZips) {
       this.classesDexZip = classesDexZip;
       this.javaResourceJar = javaResourceJar;
-      this.shardDexZips = ImmutableList.copyOf(shardDexZips);
+      this.shardDexZips = Preconditions.checkNotNull(shardDexZips);
     }
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
index 2b6b4a3..3cd1ddb 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
@@ -73,7 +73,6 @@
 import com.google.devtools.build.lib.rules.java.proto.GeneratedExtensionRegistryProvider;
 import com.google.devtools.build.lib.util.FileType;
 import com.google.devtools.build.lib.vfs.PathFragment;
-import java.util.Collection;
 import java.util.List;
 
 /**
@@ -823,7 +822,7 @@
 
   static CcInfo getCcInfo(
       final Iterable<? extends TransitiveInfoCollection> deps,
-      final Collection<String> linkOpts,
+      final ImmutableList<String> linkOpts,
       Label label,
       SymbolGenerator<?> symbolGenerator) {
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java
index 8b7af40..24011e6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java
@@ -338,7 +338,7 @@
   public CcCompilationHelper fromCommon(CcCommon common, ImmutableList<String> additionalCopts) {
     Preconditions.checkNotNull(additionalCopts);
 
-    setCopts(Iterables.concat(common.getCopts(), additionalCopts));
+    setCopts(ImmutableList.copyOf(Iterables.concat(common.getCopts(), additionalCopts)));
     addDefines(common.getDefines());
     addNonTransitiveDefines(common.getNonTransitiveDefines());
     setLooseIncludeDirs(common.getLooseIncludeDirs());
@@ -552,8 +552,8 @@
     return ImmutableSet.copyOf(this.compilationUnitSources.values());
   }
 
-  public CcCompilationHelper setCopts(Iterable<String> copts) {
-    this.copts = ImmutableList.copyOf(copts);
+  public CcCompilationHelper setCopts(ImmutableList<String> copts) {
+    this.copts = Preconditions.checkNotNull(copts);
     return this;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingContext.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingContext.java
index 1bd36a3..3672015 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingContext.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingContext.java
@@ -52,8 +52,8 @@
     private final ImmutableList<String> linkOptions;
     private final Object symbolForEquality;
 
-    private LinkOptions(Iterable<String> linkOptions, Object symbolForEquality) {
-      this.linkOptions = ImmutableList.copyOf(linkOptions);
+    private LinkOptions(ImmutableList<String> linkOptions, Object symbolForEquality) {
+      this.linkOptions = Preconditions.checkNotNull(linkOptions);
       this.symbolForEquality = Preconditions.checkNotNull(symbolForEquality);
     }
 
@@ -61,7 +61,8 @@
       return linkOptions;
     }
 
-    public static LinkOptions of(Iterable<String> linkOptions, SymbolGenerator<?> symbolGenerator) {
+    public static LinkOptions of(
+        ImmutableList<String> linkOptions, SymbolGenerator<?> symbolGenerator) {
       return new LinkOptions(linkOptions, symbolGenerator.generate());
     }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingHelper.java
index 5df148a..0938d5f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingHelper.java
@@ -377,7 +377,8 @@
                   linkopts.isEmpty()
                       ? ImmutableList.of()
                       : ImmutableList.of(
-                          CcLinkingContext.LinkOptions.of(linkopts, symbolGenerator)))
+                          CcLinkingContext.LinkOptions.of(
+                              ImmutableList.copyOf(linkopts), symbolGenerator)))
               .addLibraries(librariesToLink)
               .addNonCodeInputs(nonCodeLinkerInputs)
               .addLinkstamps(linkstampBuilder.build())
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
index 32d677d..8806e8f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
@@ -1681,7 +1681,9 @@
                     .collect(ImmutableList.toImmutableList()))
             .addDefines(defines.getContents(String.class, "defines"))
             .addNonTransitiveDefines(localDefines.getContents(String.class, "local_defines"))
-            .setCopts(userCompileFlags.getContents(String.class, "user_compile_flags"))
+            .setCopts(
+                ImmutableList.copyOf(
+                    userCompileFlags.getContents(String.class, "user_compile_flags")))
             .addAdditionalCompilationInputs(headersForClifDoNotUseThisParam)
             .addAdditionalCompilationInputs(
                 additionalInputs.getContents(Artifact.class, "additional_inputs"))
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
index 41af1f8..22d01bc 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
@@ -279,7 +279,8 @@
     this.useHeaderModules = useHeaderModules;
     this.ccCompilationContext = ccCompilationContext;
     this.builtinIncludeFiles = builtinIncludeFiles;
-    this.additionalIncludeScanningRoots = ImmutableList.copyOf(additionalIncludeScanningRoots);
+    this.additionalIncludeScanningRoots =
+        Preconditions.checkNotNull(additionalIncludeScanningRoots);
     this.compileCommandLine =
         buildCommandLine(
             sourceFile, coptsFilter, actionName, dotdFile, featureConfiguration, variables);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/DeployArchiveBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/java/DeployArchiveBuilder.java
index 8efc785..281b5a6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/DeployArchiveBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/DeployArchiveBuilder.java
@@ -138,8 +138,8 @@
   }
 
   /** Sets the list of extra lines to add to the archive's MANIFEST.MF file. */
-  public DeployArchiveBuilder setDeployManifestLines(Iterable<String> deployManifestLines) {
-    this.deployManifestLines = ImmutableList.copyOf(deployManifestLines);
+  public DeployArchiveBuilder setDeployManifestLines(ImmutableList<String> deployManifestLines) {
+    this.deployManifestLines = Preconditions.checkNotNull(deployManifestLines);
     return this;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileActionBuilder.java
index 19bea7f..26bd8fe 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileActionBuilder.java
@@ -433,8 +433,8 @@
     return this;
   }
 
-  public JavaCompileActionBuilder setJavacOpts(Iterable<String> copts) {
-    this.javacOpts = ImmutableList.copyOf(copts);
+  public JavaCompileActionBuilder setJavacOpts(ImmutableList<String> copts) {
+    this.javacOpts = Preconditions.checkNotNull(copts);
     return this;
   }
 
@@ -465,8 +465,8 @@
     return this;
   }
 
-  public JavaCompileActionBuilder setSourcePathEntries(Iterable<Artifact> sourcePathEntries) {
-    this.sourcePathEntries = ImmutableList.copyOf(sourcePathEntries);
+  public JavaCompileActionBuilder setSourcePathEntries(ImmutableList<Artifact> sourcePathEntries) {
+    this.sourcePathEntries = Preconditions.checkNotNull(sourcePathEntries);
     return this;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfoBuildHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfoBuildHelper.java
index 5f3af97..fdca401 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfoBuildHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfoBuildHelper.java
@@ -230,7 +230,7 @@
       String strictDepsMode,
       JavaToolchainProvider javaToolchain,
       JavaRuntimeInfo hostJavabase,
-      List<Artifact> sourcepathEntries,
+      ImmutableList<Artifact> sourcepathEntries,
       List<Artifact> resources,
       Boolean neverlink,
       JavaSemantics javaSemantics,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java
index c35bd31..20a3688 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java
@@ -132,13 +132,13 @@
   }
 
   /** Sets the compiler options. */
-  public JavaLibraryHelper setJavacOpts(Iterable<String> javacOpts) {
-    this.javacOpts = ImmutableList.copyOf(javacOpts);
+  public JavaLibraryHelper setJavacOpts(ImmutableList<String> javacOpts) {
+    this.javacOpts = Preconditions.checkNotNull(javacOpts);
     return this;
   }
 
-  public JavaLibraryHelper setSourcePathEntries(List<Artifact> sourcepathEntries) {
-    this.sourcePathEntries = ImmutableList.copyOf(sourcepathEntries);
+  public JavaLibraryHelper setSourcePathEntries(ImmutableList<Artifact> sourcePathEntries) {
+    this.sourcePathEntries = Preconditions.checkNotNull(sourcePathEntries);
     return this;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
index 5ea8474..fc43c2d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
@@ -96,7 +96,7 @@
             strictDepsMode,
             javaToolchain,
             hostJavabase,
-            sourcepathEntries.getContents(Artifact.class, "sourcepath"),
+            ImmutableList.copyOf(sourcepathEntries.getContents(Artifact.class, "sourcepath")),
             resources.getContents(Artifact.class, "resources"),
             neverlink,
             javaSemantics,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/MessageBundleInfo.java b/src/main/java/com/google/devtools/build/lib/rules/java/MessageBundleInfo.java
index c2dcded..90a9f68 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/MessageBundleInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/MessageBundleInfo.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.build.lib.rules.java;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
@@ -76,7 +77,7 @@
   @AutoCodec.Instantiator
   MessageBundleInfo(ImmutableList<Artifact> messages, Location location) {
     super(PROVIDER, location);
-    this.messages = ImmutableList.copyOf(messages);
+    this.messages = Preconditions.checkNotNull(messages);
   }
 
   public ImmutableList<Artifact> getMessages() {
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
index 7e3cec4..3333885 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
@@ -898,19 +898,19 @@
    */
   @VisibleForTesting
   static class CommandLineOptions {
-    private final List<String> startupArgs;
-    private final List<String> otherArgs;
+    private final ImmutableList<String> startupArgs;
+    private final ImmutableList<String> otherArgs;
 
-    CommandLineOptions(List<String> startupArgs, List<String> otherArgs) {
-      this.startupArgs = ImmutableList.copyOf(startupArgs);
-      this.otherArgs = ImmutableList.copyOf(otherArgs);
+    CommandLineOptions(ImmutableList<String> startupArgs, ImmutableList<String> otherArgs) {
+      this.startupArgs = Preconditions.checkNotNull(startupArgs);
+      this.otherArgs = Preconditions.checkNotNull(otherArgs);
     }
 
-    public List<String> getStartupArgs() {
+    public ImmutableList<String> getStartupArgs() {
       return startupArgs;
     }
 
-    public List<String> getOtherArgs() {
+    public ImmutableList<String> getOtherArgs() {
       return otherArgs;
     }
   }
@@ -957,7 +957,8 @@
         }
       }
     }
-    return new CommandLineOptions(startupArgs, otherArgs);
+    return new CommandLineOptions(
+        ImmutableList.copyOf(startupArgs), ImmutableList.copyOf(otherArgs));
   }
 
   private static InterruptSignalHandler captureSigint() {
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/AbstractSandboxSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/AbstractSandboxSpawnRunner.java
index 12cd142..9e39874 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/AbstractSandboxSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/AbstractSandboxSpawnRunner.java
@@ -17,6 +17,7 @@
 import static java.nio.charset.StandardCharsets.UTF_8;
 
 import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.devtools.build.lib.actions.ActionExecutionMetadata;
 import com.google.devtools.build.lib.actions.ExecException;
@@ -156,7 +157,7 @@
     subprocessBuilder.setStdout(outErr.getOutputPath().getPathFile());
     subprocessBuilder.setStderr(outErr.getErrorPath().getPathFile());
     subprocessBuilder.setEnv(sandbox.getEnvironment());
-    subprocessBuilder.setArgv(sandbox.getArguments());
+    subprocessBuilder.setArgv(ImmutableList.copyOf(sandbox.getArguments()));
     boolean useSubprocessTimeout = sandbox.useSubprocessTimeout();
     if (useSubprocessTimeout) {
       subprocessBuilder.setTimeoutMillis(timeout.toMillis());
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxedSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxedSpawnRunner.java
index 297ca89..bbc25b9 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxedSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxedSpawnRunner.java
@@ -47,7 +47,6 @@
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import javax.annotation.Nullable;
 
@@ -229,7 +228,7 @@
     sandboxExecRoot.getParentDirectory().createDirectory();
     sandboxExecRoot.createDirectory();
 
-    Map<String, String> environment =
+    ImmutableMap<String, String> environment =
         localEnvProvider.rewriteLocalEnv(spawn.getEnvironment(), binTools, "/tmp");
 
     final HashSet<Path> writableDirs = new HashSet<>(alwaysWritableDirs);
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/DockerSandboxedSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/DockerSandboxedSpawnRunner.java
index de65c3f..c969dff 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/DockerSandboxedSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/DockerSandboxedSpawnRunner.java
@@ -17,6 +17,7 @@
 import build.bazel.remote.execution.v2.Platform;
 import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.MoreCollectors;
 import com.google.common.eventbus.Subscribe;
@@ -51,7 +52,6 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.UUID;
@@ -213,7 +213,7 @@
     sandboxExecRoot.getParentDirectory().createDirectory();
     sandboxExecRoot.createDirectory();
 
-    Map<String, String> environment =
+    ImmutableMap<String, String> environment =
         localEnvProvider.rewriteLocalEnv(spawn.getEnvironment(), binTools, "/tmp");
 
     SandboxOutputs outputs = SandboxHelpers.getOutputs(spawn);
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java
index ca62f1d..f95b528 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java
@@ -153,7 +153,7 @@
     sandboxExecRoot.getParentDirectory().createDirectory();
     sandboxExecRoot.createDirectory();
 
-    Map<String, String> environment =
+    ImmutableMap<String, String> environment =
         localEnvProvider.rewriteLocalEnv(spawn.getEnvironment(), binTools, "/tmp");
 
     ImmutableSet<Path> writableDirs = getWritableDirs(sandboxExecRoot, environment);
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/ProcessWrapperSandboxedSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/ProcessWrapperSandboxedSpawnRunner.java
index 4bf3650..4ae82d7 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/ProcessWrapperSandboxedSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/ProcessWrapperSandboxedSpawnRunner.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.build.lib.sandbox;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.actions.ExecException;
 import com.google.devtools.build.lib.actions.Spawn;
 import com.google.devtools.build.lib.exec.TreeDeleter;
@@ -24,7 +25,6 @@
 import com.google.devtools.build.lib.vfs.Path;
 import java.io.IOException;
 import java.time.Duration;
-import java.util.Map;
 
 /** Strategy that uses sandboxing to execute a process. */
 final class ProcessWrapperSandboxedSpawnRunner extends AbstractSandboxSpawnRunner {
@@ -80,7 +80,7 @@
     sandboxExecRoot.getParentDirectory().createDirectory();
     sandboxExecRoot.createDirectory();
 
-    Map<String, String> environment =
+    ImmutableMap<String, String> environment =
         localEnvProvider.rewriteLocalEnv(spawn.getEnvironment(), binTools, "/tmp");
 
     Duration timeout = context.getTimeout();
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/WindowsSandboxUtil.java b/src/main/java/com/google/devtools/build/lib/sandbox/WindowsSandboxUtil.java
index 63b70a8..93a0696 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/WindowsSandboxUtil.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/WindowsSandboxUtil.java
@@ -49,7 +49,7 @@
     try {
       process =
           new SubprocessBuilder()
-              .setArgv(binary.getPathString(), "-h")
+              .setArgv(ImmutableList.of(binary.getPathString(), "-h"))
               .setStdout(StreamAction.STREAM)
               .redirectErrorStream(true)
               .setWorkingDirectory(new File("."))
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/WindowsSandboxedSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/WindowsSandboxedSpawnRunner.java
index 10df1aa..01bcc19 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/WindowsSandboxedSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/WindowsSandboxedSpawnRunner.java
@@ -59,9 +59,8 @@
     Path commandTmpDir = tmpDir.getRelative("work");
     commandTmpDir.createDirectory();
     ImmutableMap<String, String> environment =
-        ImmutableMap.copyOf(
-            localEnvProvider.rewriteLocalEnv(
-                spawn.getEnvironment(), binTools, commandTmpDir.getPathString()));
+        localEnvProvider.rewriteLocalEnv(
+            spawn.getEnvironment(), binTools, commandTmpDir.getPathString());
 
     SandboxInputs readablePaths =
         SandboxHelpers.processInputFiles(
diff --git a/src/main/java/com/google/devtools/build/lib/shell/SubprocessBuilder.java b/src/main/java/com/google/devtools/build/lib/shell/SubprocessBuilder.java
index e962e14..36c9cfa 100644
--- a/src/main/java/com/google/devtools/build/lib/shell/SubprocessBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/shell/SubprocessBuilder.java
@@ -19,7 +19,6 @@
 import com.google.common.collect.ImmutableMap;
 import java.io.File;
 import java.io.IOException;
-import java.util.Arrays;
 import java.util.Map;
 import javax.annotation.Nullable;
 
@@ -89,8 +88,8 @@
    * @throws IllegalArgumentException if argv is empty, or its first element (which becomes
    *     this.argv[0]) is neither an absolute path nor just a single file name
    */
-  public SubprocessBuilder setArgv(Iterable<String> argv) {
-    this.argv = ImmutableList.copyOf(argv);
+  public SubprocessBuilder setArgv(ImmutableList<String> argv) {
+    this.argv = Preconditions.checkNotNull(argv);
     Preconditions.checkArgument(!this.argv.isEmpty());
     File argv0 = new File(this.argv.get(0));
     Preconditions.checkArgument(
@@ -101,11 +100,6 @@
     return this;
   }
 
-  public SubprocessBuilder setArgv(String... argv) {
-    this.setArgv(Arrays.asList(argv));
-    return this;
-  }
-
   public ImmutableMap<String, String> getEnv() {
     return env;
   }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternPhaseFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternPhaseFunction.java
index 1d4e59a..3ebdae0 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternPhaseFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternPhaseFunction.java
@@ -236,7 +236,7 @@
                 testFilteredTargets,
                 options.getTargetPatterns(),
                 expandedTargets.getTargets(),
-                failedPatterns,
+                ImmutableList.copyOf(failedPatterns),
                 mapOriginalPatternsToLabels(expandedPatterns, targets.getTargets())));
     env.getListener()
         .post(new LoadingPhaseCompleteEvent(result.getTargetLabels(), removedTargetLabels));
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/DefStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/DefStatement.java
index 5ac3926..1fe77f5 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/DefStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/DefStatement.java
@@ -13,6 +13,7 @@
 // limitations under the License.
 package com.google.devtools.build.lib.syntax;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
 /** Syntax node for a 'def' statement, which defines a function. */
@@ -25,13 +26,13 @@
 
   DefStatement(
       Identifier identifier,
-      Iterable<Parameter> parameters,
+      ImmutableList<Parameter> parameters,
       FunctionSignature signature,
-      Iterable<Statement> statements) {
+      ImmutableList<Statement> statements) {
     this.identifier = identifier;
-    this.parameters = ImmutableList.copyOf(parameters);
+    this.parameters = Preconditions.checkNotNull(parameters);
     this.signature = signature;
-    this.statements = ImmutableList.copyOf(statements);
+    this.statements = Preconditions.checkNotNull(statements);
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
index 927a15d..eb729db 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
@@ -1242,7 +1242,7 @@
     expect(TokenKind.DEF);
     Identifier ident = parseIdent();
     expect(TokenKind.LPAREN);
-    List<Parameter> params = parseParameters();
+    ImmutableList<Parameter> params = parseParameters();
 
     FunctionSignature signature;
     try {
@@ -1255,7 +1255,7 @@
 
     expect(TokenKind.RPAREN);
     expect(TokenKind.COLON);
-    List<Statement> block = parseSuite();
+    ImmutableList<Statement> block = ImmutableList.copyOf(parseSuite());
     DefStatement stmt = new DefStatement(ident, params, signature, block);
     int end = block.isEmpty() ? token.left : Iterables.getLast(block).getEndOffset();
     return setLocation(stmt, start, end);
diff --git a/src/main/java/com/google/devtools/build/lib/versioning/GnuVersionParser.java b/src/main/java/com/google/devtools/build/lib/versioning/GnuVersionParser.java
index fddaea5..962f350 100644
--- a/src/main/java/com/google/devtools/build/lib/versioning/GnuVersionParser.java
+++ b/src/main/java/com/google/devtools/build/lib/versioning/GnuVersionParser.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.build.lib.versioning;
 
+import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.shell.Subprocess;
 import com.google.devtools.build.lib.shell.SubprocessBuilder;
 import com.google.devtools.build.lib.shell.SubprocessBuilder.StreamAction;
@@ -125,7 +126,7 @@
   public VersionT fromProgram(PathFragment program) throws IOException, ParseException {
     Subprocess process =
         new SubprocessBuilder()
-            .setArgv(program.getPathString(), "--version")
+            .setArgv(ImmutableList.of(program.getPathString(), "--version"))
             .setStdout(StreamAction.STREAM)
             .redirectErrorStream(true)
             .start();
diff --git a/src/main/java/com/google/devtools/build/lib/worker/Worker.java b/src/main/java/com/google/devtools/build/lib/worker/Worker.java
index 32e4960..abf22ec 100644
--- a/src/main/java/com/google/devtools/build/lib/worker/Worker.java
+++ b/src/main/java/com/google/devtools/build/lib/worker/Worker.java
@@ -13,6 +13,7 @@
 // limitations under the License.
 package com.google.devtools.build.lib.worker;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.hash.HashCode;
 import com.google.devtools.build.lib.sandbox.SandboxHelpers.SandboxInputs;
 import com.google.devtools.build.lib.sandbox.SandboxHelpers.SandboxOutputs;
@@ -76,11 +77,12 @@
   }
 
   void createProcess() throws IOException {
-    List<String> args = workerKey.getArgs();
+    ImmutableList<String> args = workerKey.getArgs();
     File executable = new File(args.get(0));
     if (!executable.isAbsolute() && executable.getParent() != null) {
-      args = new ArrayList<>(args);
-      args.set(0, new File(workDir.getPathFile(), args.get(0)).getAbsolutePath());
+      List<String> newArgs = new ArrayList<>(args);
+      newArgs.set(0, new File(workDir.getPathFile(), newArgs.get(0)).getAbsolutePath());
+      args = ImmutableList.copyOf(newArgs);
     }
     SubprocessBuilder processBuilder = new SubprocessBuilder();
     processBuilder.setArgv(args);
diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerKey.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerKey.java
index 5de1ce7..ab96192 100644
--- a/src/main/java/com/google/devtools/build/lib/worker/WorkerKey.java
+++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerKey.java
@@ -20,8 +20,6 @@
 import com.google.devtools.build.lib.actions.Spawns;
 import com.google.devtools.build.lib.vfs.Path;
 import com.google.devtools.build.lib.vfs.PathFragment;
-import java.util.List;
-import java.util.Map;
 import java.util.SortedMap;
 
 /**
@@ -46,8 +44,8 @@
   private final boolean proxied;
 
   WorkerKey(
-      List<String> args,
-      Map<String, String> env,
+      ImmutableList<String> args,
+      ImmutableMap<String, String> env,
       Path execRoot,
       String mnemonic,
       HashCode workerFilesCombinedHash,
@@ -55,9 +53,9 @@
       boolean mustBeSandboxed,
       boolean proxied) {
     /** Build options. */
-    this.args = ImmutableList.copyOf(Preconditions.checkNotNull(args));
+    this.args = Preconditions.checkNotNull(args);
     /** Environment variables. */
-    this.env = ImmutableMap.copyOf(Preconditions.checkNotNull(env));
+    this.env = Preconditions.checkNotNull(env);
     /** Execution root of Bazel process. */
     this.execRoot = Preconditions.checkNotNull(execRoot);
     /** Mnemonic of the worker. */
diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerMultiplexer.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerMultiplexer.java
index 822c6a0..536088e 100644
--- a/src/main/java/com/google/devtools/build/lib/worker/WorkerMultiplexer.java
+++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerMultiplexer.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.build.lib.worker;
 
+import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.shell.Subprocess;
 import com.google.devtools.build.lib.shell.SubprocessBuilder;
 import com.google.devtools.build.lib.vfs.Path;
@@ -77,11 +78,12 @@
   public synchronized void createProcess(WorkerKey workerKey, Path workDir, Path logFile)
       throws IOException {
     if (this.process == null) {
-      List<String> args = workerKey.getArgs();
+      ImmutableList<String> args = workerKey.getArgs();
       File executable = new File(args.get(0));
       if (!executable.isAbsolute() && executable.getParent() != null) {
-        args = new ArrayList<>(args);
-        args.set(0, new File(workDir.getPathFile(), args.get(0)).getAbsolutePath());
+        List<String> newArgs = new ArrayList<>(args);
+        newArgs.set(0, new File(workDir.getPathFile(), newArgs.get(0)).getAbsolutePath());
+        args = ImmutableList.copyOf(newArgs);
       }
       SubprocessBuilder processBuilder = new SubprocessBuilder();
       processBuilder.setArgv(args);
diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java
index 1471fe6..a11fb63 100644
--- a/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java
@@ -19,6 +19,7 @@
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Multimap;
 import com.google.common.hash.HashCode;
 import com.google.devtools.build.lib.actions.ActionExecutionMetadata;
@@ -53,7 +54,6 @@
 import java.time.Duration;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 import java.util.SortedMap;
 import java.util.regex.Pattern;
 
@@ -154,7 +154,7 @@
     // its args and put them into the WorkRequest instead.
     List<String> flagFiles = new ArrayList<>();
     ImmutableList<String> workerArgs = splitSpawnArgsIntoWorkerArgsAndFlagFiles(spawn, flagFiles);
-    Map<String, String> env =
+    ImmutableMap<String, String> env =
         localEnvProvider.rewriteLocalEnv(spawn.getEnvironment(), binTools, "/tmp");
 
     MetadataProvider inputFileCache = context.getMetadataProvider();
diff --git a/src/test/java/com/google/devtools/build/lib/exec/local/LocalSpawnRunnerTest.java b/src/test/java/com/google/devtools/build/lib/exec/local/LocalSpawnRunnerTest.java
index a1af0b3..f3a192d 100644
--- a/src/test/java/com/google/devtools/build/lib/exec/local/LocalSpawnRunnerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/exec/local/LocalSpawnRunnerTest.java
@@ -292,9 +292,9 @@
 
   private Logger logger;
 
-  private static Map<String, String> keepLocalEnvUnchanged(
+  private static ImmutableMap<String, String> keepLocalEnvUnchanged(
       Map<String, String> env, BinTools binTools, String fallbackTmpDir) {
-    return env;
+    return ImmutableMap.copyOf(env);
   }
 
   @Before
diff --git a/src/test/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategyTest.java b/src/test/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategyTest.java
index f9c7b96..29a8875 100644
--- a/src/test/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategyTest.java
+++ b/src/test/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategyTest.java
@@ -49,6 +49,7 @@
 import com.google.devtools.build.lib.exec.RunfilesTreeUpdater;
 import com.google.devtools.build.lib.exec.SingleBuildFileCache;
 import com.google.devtools.build.lib.exec.SpawnActionContextMaps;
+import com.google.devtools.build.lib.exec.local.LocalEnvProvider;
 import com.google.devtools.build.lib.exec.local.LocalExecutionOptions;
 import com.google.devtools.build.lib.exec.local.LocalSpawnRunner;
 import com.google.devtools.build.lib.integration.util.IntegrationMock;
@@ -64,6 +65,7 @@
 import java.io.IOException;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -147,7 +149,15 @@
                                 execRoot,
                                 localExecutionOptions,
                                 resourceManager,
-                                (env, unusedBinTools, unusedFallbackTempDir) -> env,
+                                new LocalEnvProvider() {
+                                  @Override
+                                  public ImmutableMap<String, String> rewriteLocalEnv(
+                                      Map<String, String> env,
+                                      BinTools binTools,
+                                      String fallbackTmpDir) {
+                                    return ImmutableMap.copyOf(env);
+                                  }
+                                },
                                 BinTools.forIntegrationTesting(directories, ImmutableList.of()),
                                 Mockito.mock(RunfilesTreeUpdater.class)))))),
             ImmutableList.of());
diff --git a/src/test/java/com/google/devtools/build/lib/windows/WindowsSubprocessTest.java b/src/test/java/com/google/devtools/build/lib/windows/WindowsSubprocessTest.java
index 77ccd85..8c3ad38 100644
--- a/src/test/java/com/google/devtools/build/lib/windows/WindowsSubprocessTest.java
+++ b/src/test/java/com/google/devtools/build/lib/windows/WindowsSubprocessTest.java
@@ -17,6 +17,7 @@
 import static com.google.common.truth.Truth.assertThat;
 import static java.nio.charset.StandardCharsets.UTF_8;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.shell.ShellUtils;
 import com.google.devtools.build.lib.shell.Subprocess;
@@ -66,7 +67,7 @@
   public void testSystemRootIsSetByDefault() throws Exception {
     SubprocessBuilder subprocessBuilder = new SubprocessBuilder(WindowsSubprocessFactory.INSTANCE);
     subprocessBuilder.setWorkingDirectory(new File("."));
-    subprocessBuilder.setArgv(mockBinary, "-jar", mockSubprocess, "O$SYSTEMROOT");
+    subprocessBuilder.setArgv(ImmutableList.of(mockBinary, "-jar", mockSubprocess, "O$SYSTEMROOT"));
     process = subprocessBuilder.start();
     process.waitFor();
     assertThat(process.exitValue()).isEqualTo(0);
@@ -80,7 +81,8 @@
   public void testSystemDriveIsSetByDefault() throws Exception {
     SubprocessBuilder subprocessBuilder = new SubprocessBuilder(WindowsSubprocessFactory.INSTANCE);
     subprocessBuilder.setWorkingDirectory(new File("."));
-    subprocessBuilder.setArgv(mockBinary, "-jar", mockSubprocess, "O$SYSTEMDRIVE");
+    subprocessBuilder.setArgv(
+        ImmutableList.of(mockBinary, "-jar", mockSubprocess, "O$SYSTEMDRIVE"));
     process = subprocessBuilder.start();
     process.waitFor();
     assertThat(process.exitValue()).isEqualTo(0);
@@ -94,7 +96,7 @@
   public void testSystemRootIsSet() throws Exception {
     SubprocessBuilder subprocessBuilder = new SubprocessBuilder(WindowsSubprocessFactory.INSTANCE);
     subprocessBuilder.setWorkingDirectory(new File("."));
-    subprocessBuilder.setArgv(mockBinary, "-jar", mockSubprocess, "O$SYSTEMROOT");
+    subprocessBuilder.setArgv(ImmutableList.of(mockBinary, "-jar", mockSubprocess, "O$SYSTEMROOT"));
     // Case shouldn't matter on Windows
     subprocessBuilder.setEnv(ImmutableMap.of("SystemRoot", "C:\\MySystemRoot"));
     process = subprocessBuilder.start();
@@ -110,7 +112,8 @@
   public void testSystemDriveIsSet() throws Exception {
     SubprocessBuilder subprocessBuilder = new SubprocessBuilder(WindowsSubprocessFactory.INSTANCE);
     subprocessBuilder.setWorkingDirectory(new File("."));
-    subprocessBuilder.setArgv(mockBinary, "-jar", mockSubprocess, "O$SYSTEMDRIVE");
+    subprocessBuilder.setArgv(
+        ImmutableList.of(mockBinary, "-jar", mockSubprocess, "O$SYSTEMDRIVE"));
     // Case shouldn't matter on Windows
     subprocessBuilder.setEnv(ImmutableMap.of("SystemDrive", "X:"));
     process = subprocessBuilder.start();
@@ -152,7 +155,7 @@
       SubprocessBuilder subprocessBuilder =
           new SubprocessBuilder(WindowsSubprocessFactory.INSTANCE);
       subprocessBuilder.setWorkingDirectory(new File("."));
-      subprocessBuilder.setArgv(printArgExe, arg.original);
+      subprocessBuilder.setArgv(ImmutableList.of(printArgExe, arg.original));
       process = subprocessBuilder.start();
       process.waitFor();
       assertThat(process.exitValue()).isEqualTo(0);