Fix assorted ErrorProne warnings.

RELNOTES: None.
PiperOrigin-RevId: 167574104
diff --git a/src/main/java/com/google/devtools/build/lib/actions/Actions.java b/src/main/java/com/google/devtools/build/lib/actions/Actions.java
index 8a49af4..b53a683 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/Actions.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/Actions.java
@@ -248,6 +248,7 @@
     }
 
     @Nullable
+    @Override
     public ActionAnalysisMetadata getGeneratingAction(Artifact artifact) {
       return generatingActions.get(artifact);
     }
diff --git a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
index e6148ad..9716014 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
@@ -111,6 +111,7 @@
     implements FileType.HasFilename, ActionInput, SkylarkValue, Comparable<Object> {
 
   /** Compares artifact according to their exec paths. Sorts null values first. */
+  @SuppressWarnings("ReferenceEquality")  // "a == b" is an optimization
   public static final Comparator<Artifact> EXEC_PATH_COMPARATOR =
       (a, b) -> {
         if (a == b) {
@@ -349,6 +350,7 @@
     structField = true,
     doc = "Returns true if this is a source file, i.e. it is not generated."
   )
+  @SuppressWarnings("ReferenceEquality")  // == is an optimization
   public final boolean isSourceArtifact() {
     return execPath == rootRelativePath;
   }
diff --git a/src/main/java/com/google/devtools/build/lib/actions/MutableActionGraph.java b/src/main/java/com/google/devtools/build/lib/actions/MutableActionGraph.java
index 035afdc..1b1955a 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/MutableActionGraph.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/MutableActionGraph.java
@@ -195,8 +195,8 @@
               && aPrimaryInput.toString().equals(bPrimaryInput.toString()))) {
         Artifact aPrimaryOutput = a.getPrimaryOutput();
         Artifact bPrimaryOutput = b.getPrimaryOutput();
-        if (aPrimaryOutput != bPrimaryOutput) {
-          sb.append("Primary outputs are different objects: ")
+        if (!aPrimaryOutput.equals(bPrimaryOutput)) {
+          sb.append("Primary outputs are different: ")
               .append(System.identityHashCode(aPrimaryOutput))
               .append(", ")
               .append(System.identityHashCode(bPrimaryOutput))
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java b/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java
index e8d744b..648874f 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java
@@ -78,6 +78,7 @@
 import com.google.devtools.build.skyframe.SkyValue;
 import com.google.devtools.common.options.OptionsBase;
 import com.google.devtools.common.options.OptionsProvider;
+import java.lang.reflect.InvocationTargetException;
 import java.util.Map.Entry;
 import java.util.concurrent.atomic.AtomicBoolean;
 import javax.annotation.Nullable;
@@ -170,8 +171,10 @@
       // TODO(bazel-team): Migrate away from Class<?>
       RuleDefinition ruleDefinition;
       try {
-        ruleDefinition = handler.getValue().getRuleDefinition().newInstance();
-      } catch (IllegalAccessException | InstantiationException e) {
+        ruleDefinition = handler.getValue().getRuleDefinition().getDeclaredConstructor()
+            .newInstance();
+      } catch (IllegalAccessException | InstantiationException | NoSuchMethodException
+          | InvocationTargetException e) {
         throw new IllegalStateException(e);
       }
       builder.addRuleDefinition(ruleDefinition);
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorValue.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorValue.java
index e0d0acf..02df713 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorValue.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorValue.java
@@ -41,8 +41,8 @@
 
   @Override
   public boolean equals(Object other) {
-    return this == other || other instanceof DecompressorValue
-        && directory.equals(((DecompressorValue) other).directory);
+    return this == other || (other instanceof DecompressorValue
+        && directory.equals(((DecompressorValue) other).directory));
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java
index 98411f1..4cd184b 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java
@@ -50,6 +50,7 @@
 import com.google.devtools.build.skyframe.SkyFunctionException.Transience;
 import com.google.devtools.build.skyframe.SkyKey;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -365,7 +366,8 @@
       env.getValueOrThrow(releaseFileKey, IOException.class, FileSymlinkException.class,
           InconsistentFilesystemException.class);
 
-      releaseFileContent = new String(FileSystemUtils.readContent(releaseFilePath));
+      releaseFileContent = new String(FileSystemUtils.readContent(releaseFilePath),
+          StandardCharsets.UTF_8);
     } catch (IOException | FileSymlinkException | InconsistentFilesystemException e) {
       throw new RepositoryFunctionException(
           new IOException("Could not read " + releaseFilePath.getBaseName() + " in Android NDK: "
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShBinary.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShBinary.java
index ccada47..db313a3 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShBinary.java
@@ -71,7 +71,7 @@
 
     Artifact mainExecutable =
         (OS.getCurrent() == OS.WINDOWS) ? launcherForWindows(ruleContext, symlink, src) : symlink;
-    if (symlink != mainExecutable) {
+    if (!symlink.equals(mainExecutable)) {
       filesToBuildBuilder.add(mainExecutable);
       runfilesBuilder.addArtifact(symlink);
     }
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/LastBuildEvent.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/LastBuildEvent.java
index 767e914..b071f3e 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/LastBuildEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/LastBuildEvent.java
@@ -24,14 +24,17 @@
     this.event = event;
   }
 
+  @Override
   public BuildEventId getEventId() {
     return event.getEventId();
   }
 
+  @Override
   public Collection<BuildEventId> getChildrenEvents() {
     return event.getChildrenEvents();
   }
 
+  @Override
   public BuildEventStreamProtos.BuildEvent asStreamProto(BuildEventConverters converters) {
     return BuildEventStreamProtos.BuildEvent.newBuilder(event.asStreamProto(converters))
         .setLastMessage(true)
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/JsonFormatFileTransport.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/JsonFormatFileTransport.java
index e090f55..eca7d37 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/JsonFormatFileTransport.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/JsonFormatFileTransport.java
@@ -22,6 +22,7 @@
 import com.google.protobuf.InvalidProtocolBufferException;
 import com.google.protobuf.util.JsonFormat;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 
 /**
  * A simple {@link BuildEventTransport} that writes the JSON representation of the protocol-buffer
@@ -68,6 +69,6 @@
       protoJsonRepresentation =
           "{\"id\" : \"unknown\", \"exception\" : \"InvalidProtocolBufferException\"}\n";
     }
-    writeData(protoJsonRepresentation.getBytes());
+    writeData(protoJsonRepresentation.getBytes(StandardCharsets.UTF_8));
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/TextFormatFileTransport.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/TextFormatFileTransport.java
index dc7c2ad..974dc52 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/TextFormatFileTransport.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/TextFormatFileTransport.java
@@ -21,6 +21,7 @@
 import com.google.devtools.build.lib.buildeventstream.PathConverter;
 import com.google.protobuf.TextFormat;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 
 /**
  * A simple {@link BuildEventTransport} that writes the text representation of the protocol-buffer
@@ -58,6 +59,6 @@
         };
     String protoTextRepresentation = TextFormat.printToString(event.asStreamProto(converters));
     String line = "event {\n" + protoTextRepresentation + "}\n\n";
-    writeData(line.getBytes());
+    writeData(line.getBytes(StandardCharsets.UTF_8));
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionProgressReceiver.java b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionProgressReceiver.java
index 95fb469..b2bca8c 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionProgressReceiver.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionProgressReceiver.java
@@ -195,22 +195,23 @@
 
       @Override
       public int waitForNextCompletion(int timeoutMilliseconds) throws InterruptedException {
+        long rest = timeoutMilliseconds;
         synchronized (activityIndicator) {
           int before = completedActions.size();
           long startTime = BlazeClock.instance().currentTimeMillis();
           while (true) {
-            activityIndicator.wait(timeoutMilliseconds);
+            activityIndicator.wait(rest);
 
             int completed = completedActions.size() - before;
             long now = 0;
             if (completed > 0
-                || (startTime + timeoutMilliseconds)
+                || (startTime + rest)
                     <= (now = BlazeClock.instance().currentTimeMillis())) {
               // Some actions completed, or timeout fully elapsed.
               return completed;
             } else {
               // Spurious Wakeup -- no actions completed and there's still time to wait.
-              timeoutMilliseconds -= now - startTime; // account for elapsed wait time
+              rest -= now - startTime; // account for elapsed wait time
               startTime = now;
             }
           }
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
index cf6c4e2..83d259c 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
@@ -96,7 +96,9 @@
 import com.google.devtools.build.lib.vfs.PathFragment;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -606,7 +608,7 @@
     private final PrintWriter log;
 
     private ExplanationHandler(OutputStream log, String optionsDescription) {
-      this.log = new PrintWriter(log);
+      this.log = new PrintWriter(new OutputStreamWriter(log, StandardCharsets.UTF_8));
       this.log.println("Build options: " + optionsDescription);
     }
 
diff --git a/src/main/java/com/google/devtools/build/lib/collect/CollectionUtils.java b/src/main/java/com/google/devtools/build/lib/collect/CollectionUtils.java
index dc33350..d628725 100644
--- a/src/main/java/com/google/devtools/build/lib/collect/CollectionUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/collect/CollectionUtils.java
@@ -56,7 +56,7 @@
    * @return a collection of sets of elements that are equivalent under the
    *   specified relation.
    */
-  public static <T> Collection<Set<T>> partition(Collection<T> elements,
+  public static <T> Collection<Set<T>> partitionWithComparator(Collection<T> elements,
       Comparator<T> equivalenceRelation) {
     //  TODO(bazel-team): (2009) O(n*m) where n=|elements| and m=|eqClasses|; i.e.,
     //  quadratic.  Use Tarjan's algorithm instead.
@@ -85,7 +85,7 @@
    */
   public static <T> Collection<Set<T>> partition(Collection<T> elements,
       final EquivalenceRelation<T> equivalenceRelation) {
-    return partition(elements, (Comparator<T>) equivalenceRelation::compare);
+    return partitionWithComparator(elements, (Comparator<T>) equivalenceRelation::compare);
   }
 
   /**
diff --git a/src/main/java/com/google/devtools/build/lib/collect/ImmutableSharedKeyMap.java b/src/main/java/com/google/devtools/build/lib/collect/ImmutableSharedKeyMap.java
index 792c671..20d6fc1 100644
--- a/src/main/java/com/google/devtools/build/lib/collect/ImmutableSharedKeyMap.java
+++ b/src/main/java/com/google/devtools/build/lib/collect/ImmutableSharedKeyMap.java
@@ -153,6 +153,7 @@
   }
 
   @Override
+  @SuppressWarnings("ReferenceEquality")
   public boolean equals(Object o) {
     if (this == o) {
       return true;
diff --git a/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSet.java b/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSet.java
index 522d7e9..df23c89 100644
--- a/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSet.java
+++ b/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSet.java
@@ -345,7 +345,7 @@
           int presize = members.size();
           pos = walk(sets, members, (Object[]) child, pos + 1);
           if (presize < members.size()) {
-            memo[prepos >> 3] |= 1 << (prepos & 7);
+            memo[prepos >> 3] |= (byte) (1 << (prepos & 7));
           } else {
             // We didn't find any new nodes, so don't mark this branch as taken.
             // Rewind pos.  The rest of the array is still zeros because no one
@@ -357,7 +357,7 @@
         }
       } else {
         if (members.add((E) child)) {
-          memo[pos >> 3] |= 1 << (pos & 7);
+          memo[pos >> 3] |= (byte) (1 << (pos & 7));
         }
         ++pos;
       }
diff --git a/src/main/java/com/google/devtools/build/lib/events/Location.java b/src/main/java/com/google/devtools/build/lib/events/Location.java
index 1da66dd..8420254 100644
--- a/src/main/java/com/google/devtools/build/lib/events/Location.java
+++ b/src/main/java/com/google/devtools/build/lib/events/Location.java
@@ -309,14 +309,14 @@
    *
    * <p>If such a location is not defined, this method returns an empty string.
    */
-  public static String printPathAndLine(Location location) {
-    return (location == null) ? "" : location.printPathAndLine();
+  public static String printLocation(Location location) {
+    return (location == null) ? "" : location.printLocation();
   }
 
   /**
    * Returns this location in the format "filename:line".
    */
-  public String printPathAndLine() {
+  public String printLocation() {
     StringBuilder builder = new StringBuilder();
     PathFragment path = getPath();
     if (path != null) {
diff --git a/src/main/java/com/google/devtools/build/lib/packages/InputFile.java b/src/main/java/com/google/devtools/build/lib/packages/InputFile.java
index c04a346..acb1809 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/InputFile.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/InputFile.java
@@ -77,7 +77,7 @@
   }
 
   public boolean isLicenseSpecified() {
-    return license != null && license != License.NO_LICENSE;
+    return license != null && license.isSpecified();
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/packages/License.java b/src/main/java/com/google/devtools/build/lib/packages/License.java
index 8248d8b..6467a7e 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/License.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/License.java
@@ -289,6 +289,11 @@
     return exceptions;
   }
 
+  @SuppressWarnings("ReferenceEquality")
+  public boolean isSpecified() {
+    return this != License.NO_LICENSE;
+  }
+
   /**
    * A simple toString implementation which generates a canonical form of the
    * license. (The order of license types is guaranteed to be canonical by
@@ -310,10 +315,9 @@
    */
   @Override
   public boolean equals(Object o) {
-    return o == this ||
-        o instanceof License &&
-        ((License) o).licenseTypes.equals(this.licenseTypes) &&
-        ((License) o).exceptions.equals(this.exceptions);
+    return o == this || (o instanceof License
+        && ((License) o).licenseTypes.equals(this.licenseTypes)
+        && ((License) o).exceptions.equals(this.exceptions));
   }
 
   /**
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Package.java b/src/main/java/com/google/devtools/build/lib/packages/Package.java
index 9e4ab19..8a17fbd 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Package.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Package.java
@@ -47,6 +47,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import javax.annotation.Nullable;
 
@@ -1167,7 +1168,7 @@
       }
       if (!((InputFile) cacheInstance).isVisibilitySpecified()
           || cacheInstance.getVisibility() != visibility
-          || cacheInstance.getLicense() != license) {
+          || !Objects.equals(cacheInstance.getLicense(), license)) {
         targets.put(filename, new InputFile(
             pkg, cacheInstance.getLabel(), cacheInstance.getLocation(), visibility, license));
       }
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
index 7394213..254153f 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
@@ -782,7 +782,7 @@
               String.format("licenses for exported file '%s' declared twice",
                   inputFile.getName()));
         }
-        if (license == null && pkgBuilder.getDefaultLicense() == License.NO_LICENSE
+        if (license == null && !pkgBuilder.getDefaultLicense().isSpecified()
             && RuleClass.isThirdPartyPackage(pkgBuilder.getPackageIdentifier())) {
           throw new EvalException(ast.getLocation(),
               "third-party file '" + inputFile.getName() + "' lacks a license declaration "
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
index 7cbb25f..3a222db 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
@@ -1688,7 +1688,7 @@
       if (license == null) {
         license = pkgBuilder.getDefaultLicense();
       }
-      if (license == License.NO_LICENSE) {
+      if (!license.isSpecified()) {
         rule.reportError("third-party rule '" + rule.getLabel() + "' lacks a license declaration "
                          + "with one of the following types: notice, reciprocal, permissive, "
                          + "restricted, unencumbered, by_exception_only",
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java b/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java
index 930279b..0ff628e 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java
@@ -384,7 +384,7 @@
     // rules created from function calls in a subincluded file, even if both files share a path
     // prefix (for example, when //a/package:BUILD subincludes //a/package/with/a/subpackage:BUILD).
     // We can revert to that approach once subincludes aren't supported anymore.
-    String absolutePath = Location.printPathAndLine(location);
+    String absolutePath = Location.printLocation(location);
     int pos = absolutePath.indexOf(label.getPackageName());
     return (pos < 0) ? null : absolutePath.substring(pos);
   }
diff --git a/src/main/java/com/google/devtools/build/lib/profiler/ProfilerTask.java b/src/main/java/com/google/devtools/build/lib/profiler/ProfilerTask.java
index f983766..10560db 100644
--- a/src/main/java/com/google/devtools/build/lib/profiler/ProfilerTask.java
+++ b/src/main/java/com/google/devtools/build/lib/profiler/ProfilerTask.java
@@ -104,7 +104,7 @@
   /** How many of the slowest instances to keep. If 0, no slowest instance calculation is done. */
   public final int slowestInstancesCount;
   /** True if the metric records VFS operations */
-  private boolean vfs;
+  private final boolean vfs;
 
   ProfilerTask(String description, long minDuration, int color, int slowestInstanceCount) {
     this(description, minDuration, color, slowestInstanceCount, /*vfs=*/ false);
diff --git a/src/main/java/com/google/devtools/build/lib/query2/LabelVisitor.java b/src/main/java/com/google/devtools/build/lib/query2/LabelVisitor.java
index 86bf39f..14d1fda 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/LabelVisitor.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/LabelVisitor.java
@@ -307,8 +307,8 @@
 
       // Avoid thread-related overhead when not crossing packages.
       // Can start a new thread when count reaches 100, to prevent infinite recursion.
-      if (from != null && from.getLabel().getPackageFragment() == label.getPackageFragment() &&
-          !blockNewActions() && count < RECURSION_LIMIT) {
+      if (from != null && from.getLabel().getPackageFragment().equals(label.getPackageFragment())
+          && !blockNewActions() && count < RECURSION_LIMIT) {
         newVisitRunnable(from, attr, label, depth, count + 1).run();
       } else {
         execute(newVisitRunnable(from, attr, label, depth, 0));
diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/GraphOutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/output/GraphOutputFormatter.java
index 869901f..9640dd6 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/output/GraphOutputFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/output/GraphOutputFormatter.java
@@ -24,7 +24,9 @@
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.query2.output.QueryOptions.OrderOutput;
 import java.io.OutputStream;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -53,9 +55,11 @@
 
     boolean sortLabels = options.orderOutput == OrderOutput.FULL;
     if (options.graphFactored) {
-      outputFactored(result, new PrintWriter(out), sortLabels);
+      outputFactored(result, new PrintWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)),
+          sortLabels);
     } else {
-      outputUnfactored(result, new PrintWriter(out), sortLabels, options);
+      outputUnfactored(result, new PrintWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)),
+          sortLabels, options);
     }
   }
 
@@ -157,6 +161,7 @@
    *
    * TODO(bazel-team): Make this a method of Digraph.
    */
+  @SuppressWarnings("ReferenceEquality")
   private static <LABEL> EquivalenceRelation<Node<LABEL>> createEquivalenceRelation() {
     return new EquivalenceRelation<Node<LABEL>>() {
       @Override
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java
index c631327..974e660 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java
@@ -309,7 +309,7 @@
       while (currentClientDescription != null) {
         switch (lockingMode) {
           case WAIT:
-            if (otherClientDescription != currentClientDescription) {
+            if (!otherClientDescription.equals(currentClientDescription)) {
               if (attempts > 0) {
                 outErr.printErrLn(" lock taken by another command");
               }
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 66defce..9bb2d95 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
@@ -828,6 +828,7 @@
   /**
    * Creates and returns a new Blaze RPCServer. Call {@link RPCServer#serve()} to start the server.
    */
+  @SuppressWarnings("LiteralClassName")  // bootstrap binary does not have gRPC
   private static RPCServer createBlazeRPCServer(
       Iterable<BlazeModule> modules, List<String> args)
       throws IOException, OptionsParsingException, AbruptExitException {
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java
index fd91fab..cbfdb5e 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java
@@ -40,12 +40,14 @@
 import com.google.devtools.build.lib.vfs.Path;
 import com.google.devtools.common.options.OptionsProvider;
 import java.io.ByteArrayOutputStream;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.lang.management.GarbageCollectorMXBean;
 import java.lang.management.ManagementFactory;
 import java.lang.management.MemoryMXBean;
 import java.lang.management.MemoryUsage;
 import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.util.Collection;
 import java.util.Map;
 
@@ -106,7 +108,8 @@
       return (byte[]) value;
     }
     ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-    PrintWriter writer = new PrintWriter(outputStream);
+    PrintWriter writer = new PrintWriter(new OutputStreamWriter(
+        outputStream, StandardCharsets.UTF_8));
     writer.print(value + "\n");
     writer.flush();
     return outputStream.toByteArray();
@@ -436,7 +439,7 @@
         throws AbruptExitException {
       // The documentation is not very clear on what it means to have more than
       // one GC MXBean, so we just sum them up.
-      int gcCount = 0;
+      long gcCount = 0;
       for (GarbageCollectorMXBean gcBean : ManagementFactory.getGarbageCollectorMXBeans()) {
         gcCount += gcBean.getCollectionCount();
       }
@@ -532,7 +535,7 @@
         throws AbruptExitException {
       // The documentation is not very clear on what it means to have more than
       // one GC MXBean, so we just sum them up.
-      int gcTime = 0;
+      long gcTime = 0;
       for (GarbageCollectorMXBean gcBean : ManagementFactory.getGarbageCollectorMXBeans()) {
         gcTime += gcBean.getCollectionTime();
       }
diff --git a/src/main/java/com/google/devtools/build/lib/shell/CommandResult.java b/src/main/java/com/google/devtools/build/lib/shell/CommandResult.java
index 24e0947..4a6f4f7 100644
--- a/src/main/java/com/google/devtools/build/lib/shell/CommandResult.java
+++ b/src/main/java/com/google/devtools/build/lib/shell/CommandResult.java
@@ -35,7 +35,7 @@
     new ByteArrayOutputStream() {
 
       @Override
-      public byte[] toByteArray() {
+      public synchronized byte[] toByteArray() {
         return NO_BYTES;
       }
   };
@@ -44,7 +44,7 @@
     new ByteArrayOutputStream(){
 
       @Override
-      public byte[] toByteArray() {
+      public synchronized byte[] toByteArray() {
         throw new IllegalStateException("Output was not collected");
       }
   };
diff --git a/src/main/java/com/google/devtools/build/lib/shell/LogUtil.java b/src/main/java/com/google/devtools/build/lib/shell/LogUtil.java
index c2e055e..44cac2c 100644
--- a/src/main/java/com/google/devtools/build/lib/shell/LogUtil.java
+++ b/src/main/java/com/google/devtools/build/lib/shell/LogUtil.java
@@ -13,6 +13,8 @@
 // limitations under the License.
 package com.google.devtools.build.lib.shell;
 
+import java.nio.charset.StandardCharsets;
+
 /**
  * Utilities for logging.
  */
@@ -38,7 +40,7 @@
      */
     try {
       if (bytes.length > TRUNCATE_STRINGS_AT) {
-        return new String(bytes, 0, TRUNCATE_STRINGS_AT)
+        return new String(bytes, 0, TRUNCATE_STRINGS_AT, StandardCharsets.UTF_8)
           + "[... truncated. original size was " + bytes.length + " bytes.]";
       }
       return new String(bytes);
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/EvalExceptionWithStackTrace.java b/src/main/java/com/google/devtools/build/lib/syntax/EvalExceptionWithStackTrace.java
index 713f57f..173f2f7 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/EvalExceptionWithStackTrace.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/EvalExceptionWithStackTrace.java
@@ -25,7 +25,7 @@
  */
 public class EvalExceptionWithStackTrace extends EvalException {
 
-  private StackTraceElement mostRecentElement;
+  private StackFrame mostRecentElement;
 
   public EvalExceptionWithStackTrace(Exception original, ASTNode culprit) {
     super(extractLocation(original, culprit), getNonEmptyMessage(original), getCause(original));
@@ -119,7 +119,7 @@
     if (mostRecentElement != null && isSameLocation(location, mostRecentElement.getLocation())) {
       return;
     }
-    mostRecentElement = new StackTraceElement(label, location, mostRecentElement, canPrint);
+    mostRecentElement = new StackFrame(label, location, mostRecentElement, canPrint);
   }
 
   /**
@@ -178,13 +178,13 @@
    * An element in the stack trace which contains the name of the offending function / rule /
    * statement and its location.
    */
-  protected static final class StackTraceElement {
+  protected static final class StackFrame {
     private final String label;
     private final Location location;
-    private final StackTraceElement cause;
+    private final StackFrame cause;
     private final boolean canPrint;
 
-    StackTraceElement(String label, Location location, StackTraceElement cause, boolean canPrint) {
+    StackFrame(String label, Location location, StackFrame cause, boolean canPrint) {
       this.label = label;
       this.location = location;
       this.cause = cause;
@@ -199,7 +199,7 @@
       return location;
     }
 
-    StackTraceElement getCause() {
+    StackFrame getCause() {
       return cause;
     }
 
@@ -223,11 +223,11 @@
     /**
      * Turns the given message and StackTraceElements into a string.
      */
-    public final String print(String message, StackTraceElement mostRecentElement) {
+    public final String print(String message, StackFrame mostRecentElement) {
       Deque<String> output = new LinkedList<>();
 
       // Adds dummy element for the rule call that uses the location of the top-most function.
-      mostRecentElement = new StackTraceElement("", mostRecentElement.getLocation(),
+      mostRecentElement = new StackFrame("", mostRecentElement.getLocation(),
           (mostRecentElement.getCause() == null) ? null : mostRecentElement, true);
 
       while (mostRecentElement != null) {
@@ -248,14 +248,14 @@
     /**
      * Returns the location of the given element or Location.BUILTIN if the element is null.
      */
-    private Location getLocation(StackTraceElement element) {
+    private Location getLocation(StackFrame element) {
       return (element == null) ? Location.BUILTIN : element.getLocation();
     }
 
     /**
      * Returns the string representation of the given element.
      */
-    protected String print(StackTraceElement element) {
+    protected String print(StackFrame element) {
       // Similar to Python, the first (most-recent) entry in the stack frame is printed only once.
       // Consequently, we skip it here.
       if (element.getCause() == null) {
diff --git a/src/main/java/com/google/devtools/build/lib/unix/Directories.java b/src/main/java/com/google/devtools/build/lib/unix/Directories.java
index aa2e958..81ed7c8 100644
--- a/src/main/java/com/google/devtools/build/lib/unix/Directories.java
+++ b/src/main/java/com/google/devtools/build/lib/unix/Directories.java
@@ -21,6 +21,7 @@
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 
 /**
  * Provides utility methods for working with directories in a Unix environment.
@@ -75,7 +76,8 @@
       new Command(new String[] {"/bin/rm", "-rf", filePath}).execute();
     } catch (AbnormalTerminationException e) {
       String message =
-          e.getResult().getTerminationStatus() + ": " + new String(e.getResult().getStderr());
+          e.getResult().getTerminationStatus() + ": " + new String(
+              e.getResult().getStderr(), StandardCharsets.UTF_8);
       throw new IOException(message, e);
     } catch (CommandException e) {
       throw new IOException(e);
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/ModifiedFileSet.java b/src/main/java/com/google/devtools/build/lib/vfs/ModifiedFileSet.java
index 0aca931..241edf6 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/ModifiedFileSet.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/ModifiedFileSet.java
@@ -54,6 +54,9 @@
 
   @Override
   public boolean equals(Object o) {
+    if (o == this) {
+      return true;
+    }
     if (!(o instanceof ModifiedFileSet)) {
       return false;
     }
@@ -68,9 +71,9 @@
 
   @Override
   public String toString() {
-    if (this == EVERYTHING_MODIFIED) {
+    if (this.equals(EVERYTHING_MODIFIED)) {
       return "EVERYTHING_MODIFIED";
-    } else if (this == NOTHING_MODIFIED) {
+    } else if (this.equals(NOTHING_MODIFIED)) {
       return "NOTHING_MODIFIED";
     } else {
       return modified.toString();
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileInfo.java b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileInfo.java
index e015cc1..f696ad9 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileInfo.java
@@ -66,13 +66,13 @@
       }
 
       @Override
-      public void write(int dataByte) {
+      public synchronized void write(int dataByte) {
         Preconditions.checkState(!closed);
         super.write(dataByte);
       }
 
       @Override
-      public void write(byte[] data, int offset, int length) {
+      public synchronized void write(byte[] data, int offset, int length) {
         Preconditions.checkState(!closed);
         super.write(data, offset, length);
       }
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/OutOfScopeDirectoryStatus.java b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/OutOfScopeDirectoryStatus.java
index 767f5ef..95d6044 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/OutOfScopeDirectoryStatus.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/OutOfScopeDirectoryStatus.java
@@ -49,22 +49,75 @@
     return new UnsupportedOperationException();
   }
 
-  @Override public boolean isDirectory() { throw failure(); }
-  @Override public boolean isSymbolicLink() { throw failure(); }
-  @Override public boolean isFile() { throw failure(); }
-  @Override public long getSize() { throw failure(); }
-  @Override protected void markModificationTime() { throw failure(); }
-  @Override public synchronized long getLastModifiedTime() { throw failure(); }
-  @Override void setLastModifiedTime(long newTime) { throw failure(); }
-  @Override public synchronized long getLastChangeTime() { throw failure(); }
-  @Override boolean isReadable() { throw failure(); }
-  @Override void setReadable(boolean readable) { throw failure(); }
-  @Override void setWritable(boolean writable) { throw failure(); }
-  @Override void setExecutable(boolean executable) { throw failure(); }
-  @Override boolean isWritable() { throw failure(); }
-  @Override boolean isExecutable() { throw failure(); }
-  @Override void addChild(String name, InMemoryContentInfo inode) { throw failure(); }
-  @Override InMemoryContentInfo getChild(String name) { throw failure(); }
-  @Override void removeChild(String name) { throw failure(); }
-  @Override Set<String> getAllChildren() { throw failure(); }
+  @Override public boolean isDirectory() {
+    throw failure();
+  }
+
+  @Override public boolean isSymbolicLink() {
+    throw failure();
+  }
+
+  @Override public boolean isFile() {
+    throw failure();
+  }
+
+  @Override public long getSize() {
+    throw failure();
+  }
+
+  @Override protected synchronized void markModificationTime() {
+    throw failure();
+  }
+
+  @Override public synchronized long getLastModifiedTime() {
+    throw failure();
+  }
+
+  @Override synchronized void setLastModifiedTime(long newTime) {
+    throw failure();
+  }
+
+  @Override public synchronized long getLastChangeTime() {
+    throw failure();
+  }
+
+  @Override boolean isReadable() {
+    throw failure();
+  }
+
+  @Override void setReadable(boolean readable) {
+    throw failure();
+  }
+
+  @Override void setWritable(boolean writable) {
+    throw failure();
+  }
+
+  @Override void setExecutable(boolean executable) {
+    throw failure();
+  }
+
+  @Override boolean isWritable() {
+    throw failure();
+  }
+
+  @Override boolean isExecutable() {
+    throw failure();
+  }
+
+  @Override synchronized void addChild(String name, InMemoryContentInfo inode) {
+    throw failure();
+  }
+
+  @Override synchronized InMemoryContentInfo getChild(String name) {
+    throw failure();
+  }
+
+  @Override synchronized void removeChild(String name) {
+    throw failure();
+  }
+
+  @Override Set<String> getAllChildren() {
+    throw failure();
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/OutOfScopeFileStatus.java b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/OutOfScopeFileStatus.java
index 287d97d..0804968 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/OutOfScopeFileStatus.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/OutOfScopeFileStatus.java
@@ -48,19 +48,63 @@
     return new UnsupportedOperationException();
   }
 
-  @Override public boolean isDirectory() { throw failure(); }
-  @Override public boolean isSymbolicLink() { throw failure(); }
-  @Override public boolean isFile() { throw failure(); }
-  @Override public boolean isSpecialFile() { throw failure(); }
-  @Override public long getSize() { throw failure(); }
-  @Override protected void markModificationTime() { throw failure(); }
-  @Override public synchronized long getLastModifiedTime() { throw failure(); }
-  @Override void setLastModifiedTime(long newTime) { throw failure(); }
-  @Override public synchronized long getLastChangeTime() { throw failure(); }
-  @Override boolean isReadable() { throw failure(); }
-  @Override void setReadable(boolean readable) { throw failure(); }
-  @Override void setWritable(boolean writable) { throw failure(); }
-  @Override boolean isWritable() { throw failure(); }
-  @Override void setExecutable(boolean executable) { throw failure(); }
-  @Override boolean isExecutable() { throw failure(); }
+  @Override public boolean isDirectory() {
+    throw failure();
+  }
+
+  @Override public boolean isSymbolicLink() {
+    throw failure();
+  }
+
+  @Override public boolean isFile() {
+    throw failure();
+  }
+
+  @Override public boolean isSpecialFile() {
+    throw failure();
+  }
+
+  @Override public long getSize() {
+    throw failure();
+  }
+
+  @Override protected synchronized void markModificationTime() {
+    throw failure();
+  }
+
+  @Override public synchronized long getLastModifiedTime() {
+    throw failure();
+  }
+
+  @Override synchronized void setLastModifiedTime(long newTime) {
+    throw failure();
+  }
+
+  @Override public synchronized long getLastChangeTime() {
+    throw failure();
+  }
+
+  @Override boolean isReadable() {
+    throw failure();
+  }
+
+  @Override void setReadable(boolean readable) {
+    throw failure();
+  }
+
+  @Override void setWritable(boolean writable) {
+    throw failure();
+  }
+
+  @Override boolean isWritable() {
+    throw failure();
+  }
+
+  @Override void setExecutable(boolean executable) {
+    throw failure();
+  }
+
+  @Override boolean isExecutable() {
+    throw failure();
+  }
 }