[errorprone] Annotate method returning null as nullable

See https://errorprone.info/bugpattern/ReturnMissingNullable

Change-Id: Ic1d29e357c6305df28760d92080c2a546675a843
diff --git a/java/com/google/gitiles/BlobSoyData.java b/java/com/google/gitiles/BlobSoyData.java
index 7e96d65..a6879ae 100644
--- a/java/com/google/gitiles/BlobSoyData.java
+++ b/java/com/google/gitiles/BlobSoyData.java
@@ -28,6 +28,7 @@
 import java.io.IOException;
 import java.util.List;
 import java.util.Map;
+import javax.annotation.Nullable;
 import org.eclipse.jgit.diff.RawText;
 import org.eclipse.jgit.errors.LargeObjectException;
 import org.eclipse.jgit.errors.MissingObjectException;
@@ -194,7 +195,7 @@
     return n < end ? n : -1;
   }
 
-  private static String extension(String path, String content) {
+  private static @Nullable String extension(String path, String content) {
     if (content.startsWith("#!/bin/sh") || content.startsWith("#!/bin/bash")) {
       return "sh";
     } else if (content.startsWith("#!/usr/bin/perl")) {
diff --git a/java/com/google/gitiles/DescribeServlet.java b/java/com/google/gitiles/DescribeServlet.java
index 545f3aa..c3b178e 100644
--- a/java/com/google/gitiles/DescribeServlet.java
+++ b/java/com/google/gitiles/DescribeServlet.java
@@ -22,6 +22,7 @@
 import java.io.Writer;
 import java.util.List;
 import java.util.Map;
+import javax.annotation.Nullable;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.eclipse.jgit.api.Git;
@@ -91,7 +92,7 @@
     }
   }
 
-  private String describe(Repository repo, GitilesView view, HttpServletRequest req)
+  private @Nullable String describe(Repository repo, GitilesView view, HttpServletRequest req)
       throws IOException {
     if (!getBooleanParam(view, CONTAINS_PARAM)) {
       throw new GitilesRequestFailureException(FailureReason.INCORECT_PARAMETER);
diff --git a/java/com/google/gitiles/DiffServlet.java b/java/com/google/gitiles/DiffServlet.java
index 03353ac..53552e9 100644
--- a/java/com/google/gitiles/DiffServlet.java
+++ b/java/com/google/gitiles/DiffServlet.java
@@ -26,6 +26,7 @@
 import java.util.Arrays;
 import java.util.Map;
 import java.util.Set;
+import javax.annotation.Nullable;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.eclipse.jgit.diff.DiffFormatter;
@@ -140,7 +141,7 @@
     }
   }
 
-  private static TreeWalk newTreeWalk(RevWalk walk, GitilesView view) throws IOException {
+  private static @Nullable TreeWalk newTreeWalk(RevWalk walk, GitilesView view) throws IOException {
     if (view.getPathPart().isEmpty()) {
       return null;
     }
diff --git a/java/com/google/gitiles/GitilesFilter.java b/java/com/google/gitiles/GitilesFilter.java
index da6044b..41c6ea4 100644
--- a/java/com/google/gitiles/GitilesFilter.java
+++ b/java/com/google/gitiles/GitilesFilter.java
@@ -229,10 +229,7 @@
     }
     root.through(dispatchFilter);
 
-    serveRegex(REPO_REGEX)
-        .through(repositoryFilter)
-        .through(viewFilter)
-        .through(dispatchFilter);
+    serveRegex(REPO_REGEX).through(repositoryFilter).through(viewFilter).through(dispatchFilter);
 
     serveRegex(REPO_PATH_REGEX)
         .through(repositoryFilter)
diff --git a/java/com/google/gitiles/GitilesView.java b/java/com/google/gitiles/GitilesView.java
index bf3937e..9bb43a9 100644
--- a/java/com/google/gitiles/GitilesView.java
+++ b/java/com/google/gitiles/GitilesView.java
@@ -39,6 +39,7 @@
 import java.util.EnumSet;
 import java.util.List;
 import java.util.Map;
+import javax.annotation.Nullable;
 import javax.servlet.http.HttpServletRequest;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.revwalk.RevObject;
@@ -561,7 +562,7 @@
     return oldRevision;
   }
 
-  public String getRevisionRange() {
+  public @Nullable String getRevisionRange() {
     if (Revision.isNull(oldRevision)) {
       if (type == Type.LOG || type == Type.DIFF) {
         // For types that require two revisions, NULL indicates the empty
diff --git a/java/com/google/gitiles/GitwebRedirectFilter.java b/java/com/google/gitiles/GitwebRedirectFilter.java
index cc8bca0..52a6965 100644
--- a/java/com/google/gitiles/GitwebRedirectFilter.java
+++ b/java/com/google/gitiles/GitwebRedirectFilter.java
@@ -32,6 +32,7 @@
 import java.net.URLDecoder;
 import java.util.List;
 import java.util.regex.Pattern;
+import javax.annotation.Nullable;
 import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
@@ -146,7 +147,7 @@
     return Iterables.getFirst(params.get(checkNotNull(name)), null);
   }
 
-  private static Revision toRevision(String rev) {
+  private static @Nullable Revision toRevision(String rev) {
     if (Strings.isNullOrEmpty(rev)) {
       return null;
     } else if ("HEAD".equals(rev) || rev.startsWith("refs/")) {
diff --git a/java/com/google/gitiles/LogServlet.java b/java/com/google/gitiles/LogServlet.java
index 51ab68d..9a66ef8 100644
--- a/java/com/google/gitiles/LogServlet.java
+++ b/java/com/google/gitiles/LogServlet.java
@@ -36,6 +36,7 @@
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
+import javax.annotation.Nullable;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.eclipse.jgit.diff.DiffConfig;
@@ -178,7 +179,8 @@
     }
   }
 
-  private static GitilesView getView(HttpServletRequest req, Repository repo) throws IOException {
+  private static @Nullable GitilesView getView(HttpServletRequest req, Repository repo)
+      throws IOException {
     GitilesView view = ViewFilter.getView(req);
     if (!Revision.isNull(view.getRevision())) {
       return view;
@@ -225,7 +227,7 @@
     }
   }
 
-  private static RevWalk newWalk(Repository repo, GitilesView view, GitilesAccess access)
+  private static @Nullable RevWalk newWalk(Repository repo, GitilesView view, GitilesAccess access)
       throws MissingObjectException, IOException {
     RevWalk walk = new RevWalk(repo);
     if (isTrue(view, FIRST_PARENT_PARAM)) {
@@ -307,8 +309,8 @@
     return Boolean.TRUE.equals(StringUtils.toBooleanOrNull(v));
   }
 
-  private static Paginator newPaginator(Repository repo, GitilesView view, GitilesAccess access)
-      throws IOException {
+  private static @Nullable Paginator newPaginator(
+      Repository repo, GitilesView view, GitilesAccess access) throws IOException {
     if (view == null) {
       return null;
     }
diff --git a/java/com/google/gitiles/LogSoyData.java b/java/com/google/gitiles/LogSoyData.java
index 34b290f..061ce23 100644
--- a/java/com/google/gitiles/LogSoyData.java
+++ b/java/com/google/gitiles/LogSoyData.java
@@ -144,7 +144,7 @@
         "entry", entry);
   }
 
-  private Map<String, Object> toRenameSoyData(DiffEntry entry) {
+  private @Nullable Map<String, Object> toRenameSoyData(DiffEntry entry) {
     if (entry == null) {
       return null;
     }
diff --git a/java/com/google/gitiles/Paginator.java b/java/com/google/gitiles/Paginator.java
index 47c4470..eed7b75 100644
--- a/java/com/google/gitiles/Paginator.java
+++ b/java/com/google/gitiles/Paginator.java
@@ -121,7 +121,8 @@
    * @throws IncorrectObjectTypeException See {@link RevWalk#next()}.
    * @throws IOException See {@link RevWalk#next()}.
    */
-  public RevCommit next() throws MissingObjectException, IncorrectObjectTypeException, IOException {
+  public @Nullable RevCommit next()
+      throws MissingObjectException, IncorrectObjectTypeException, IOException {
     if (done) {
       return null;
     }
@@ -185,7 +186,7 @@
    *
    * @return entry corresponding to a rename or copy at the given commit.
    */
-  public DiffEntry getRename(ObjectId commitId) {
+  public @Nullable DiffEntry getRename(ObjectId commitId) {
     return renamed != null ? renamed.get(commitId) : null;
   }
 
diff --git a/java/com/google/gitiles/PathServlet.java b/java/com/google/gitiles/PathServlet.java
index 9475ae7..87d2680 100644
--- a/java/com/google/gitiles/PathServlet.java
+++ b/java/com/google/gitiles/PathServlet.java
@@ -34,6 +34,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.regex.Pattern;
+import javax.annotation.Nullable;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.eclipse.jgit.errors.ConfigInvalidException;
@@ -103,7 +104,7 @@
       this.mode = mode;
     }
 
-    static FileType forEntry(TreeWalk tw) {
+    static @Nullable FileType forEntry(TreeWalk tw) {
       int mode = tw.getRawMode(0);
       for (FileType type : values()) {
         if (type.mode.equals(mode)) {
@@ -296,7 +297,7 @@
     }
   }
 
-  private static RevTree getRoot(GitilesView view, RevWalk rw) throws IOException {
+  private static @Nullable RevTree getRoot(GitilesView view, RevWalk rw) throws IOException {
     RevObject obj = rw.peel(rw.parseAny(view.getRevision().getId()));
     switch (obj.getType()) {
       case OBJ_COMMIT:
@@ -380,7 +381,8 @@
    * to help the auto-dive routine as well.
    */
   private static class WalkResult implements AutoCloseable {
-    private static WalkResult recursivePath(RevWalk rw, GitilesView view) throws IOException {
+    private static @Nullable WalkResult recursivePath(RevWalk rw, GitilesView view)
+        throws IOException {
       RevTree root = getRoot(view, rw);
       String path = view.getPathPart();
 
@@ -410,7 +412,7 @@
       return new WalkResult(tw, path, root, root, FileType.TREE, ImmutableList.<Boolean>of());
     }
 
-    private static WalkResult forPath(RevWalk rw, GitilesView view, boolean recursive)
+    private static @Nullable WalkResult forPath(RevWalk rw, GitilesView view, boolean recursive)
         throws IOException {
       if (recursive) {
         return recursivePath(rw, view);
@@ -520,8 +522,8 @@
                     .toSoyData(wr.id, wr.tw)));
   }
 
-  private CanonicalTreeParser getOnlyChildSubtree(ObjectReader reader, ObjectId id, byte[] prefix)
-      throws IOException {
+  private @Nullable CanonicalTreeParser getOnlyChildSubtree(
+      ObjectReader reader, ObjectId id, byte[] prefix) throws IOException {
     CanonicalTreeParser p = new CanonicalTreeParser(prefix, reader, id);
     if (p.eof() || p.getEntryFileMode() != FileMode.TREE) {
       return null;
@@ -655,7 +657,7 @@
     return remoteUrl != null ? remoteUrl : modulesUrl;
   }
 
-  private static String resolveHttpUrl(String remoteUrl) {
+  private static @Nullable String resolveHttpUrl(String remoteUrl) {
     if (remoteUrl == null) {
       return null;
     }
diff --git a/java/com/google/gitiles/PathUtil.java b/java/com/google/gitiles/PathUtil.java
index 2df8cdc..7d230f2 100644
--- a/java/com/google/gitiles/PathUtil.java
+++ b/java/com/google/gitiles/PathUtil.java
@@ -19,13 +19,14 @@
 import com.google.common.base.Strings;
 import com.google.common.io.Files;
 import java.util.StringTokenizer;
+import javax.annotation.Nullable;
 
 /** Static utilities for dealing with pathnames. */
 class PathUtil {
   private static final CharMatcher MATCHER = CharMatcher.is('/');
   static final Splitter SPLITTER = Splitter.on(MATCHER);
 
-  static String simplifyPathUpToRoot(String path, String root) {
+  static @Nullable String simplifyPathUpToRoot(String path, String root) {
     if (path.startsWith("/")) {
       return null;
     }
diff --git a/java/com/google/gitiles/ReadmeHelper.java b/java/com/google/gitiles/ReadmeHelper.java
index a01c7f0..389c73c 100644
--- a/java/com/google/gitiles/ReadmeHelper.java
+++ b/java/com/google/gitiles/ReadmeHelper.java
@@ -19,6 +19,7 @@
 import com.google.gitiles.doc.MarkdownConfig;
 import com.google.gitiles.doc.MarkdownToHtml;
 import java.io.IOException;
+import javax.annotation.Nullable;
 import org.eclipse.jgit.errors.CorruptObjectException;
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
 import org.eclipse.jgit.errors.MissingObjectException;
@@ -87,6 +88,7 @@
     return readmePath;
   }
 
+  @Nullable
   SafeHtml render() {
     try {
       byte[] raw = reader.open(readmeId, Constants.OBJ_BLOB).getCachedBytes(config.inputLimit);
diff --git a/java/com/google/gitiles/RepositoryIndexServlet.java b/java/com/google/gitiles/RepositoryIndexServlet.java
index 0360588..a491976 100644
--- a/java/com/google/gitiles/RepositoryIndexServlet.java
+++ b/java/com/google/gitiles/RepositoryIndexServlet.java
@@ -31,6 +31,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import javax.annotation.Nullable;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
@@ -154,7 +155,7 @@
     return list.size() > REF_LIMIT ? list.subList(0, REF_LIMIT) : list;
   }
 
-  private static Map<String, Object> renderReadme(
+  private static @Nullable Map<String, Object> renderReadme(
       HttpServletRequest req, RevWalk walk, GitilesView view, Config cfg, RevObject head)
       throws IOException {
     RevTree rootTree;
diff --git a/java/com/google/gitiles/RevisionParser.java b/java/com/google/gitiles/RevisionParser.java
index 8196267..7fbf86c 100644
--- a/java/com/google/gitiles/RevisionParser.java
+++ b/java/com/google/gitiles/RevisionParser.java
@@ -27,6 +27,7 @@
 import java.util.Optional;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import javax.annotation.Nullable;
 import org.eclipse.jgit.errors.AmbiguousObjectException;
 import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.errors.RevisionSyntaxException;
@@ -114,6 +115,7 @@
     this.branchRedirect = checkNotNull(branchRedirect, "branchRedirect");
   }
 
+  @Nullable
   Result parse(String path) throws IOException {
     if (path.startsWith("/")) {
       path = path.substring(1);
@@ -231,7 +233,7 @@
     }
   }
 
-  private RevObject resolve(String name, RevWalk walk) throws IOException {
+  private @Nullable RevObject resolve(String name, RevWalk walk) throws IOException {
     try {
       ObjectId id = repo.resolve(name);
       return id != null ? walk.parseAny(id) : null;
diff --git a/java/com/google/gitiles/TreeSoyData.java b/java/com/google/gitiles/TreeSoyData.java
index 985edfa..4e2a579 100644
--- a/java/com/google/gitiles/TreeSoyData.java
+++ b/java/com/google/gitiles/TreeSoyData.java
@@ -26,6 +26,7 @@
 import java.io.IOException;
 import java.util.List;
 import java.util.Map;
+import javax.annotation.Nullable;
 import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.ObjectId;
@@ -55,7 +56,7 @@
    */
   static final int MAX_SYMLINK_SIZE = 16 << 10;
 
-  static String resolveTargetUrl(GitilesView view, String target) {
+  static @Nullable String resolveTargetUrl(GitilesView view, String target) {
     String resolved = PathUtil.simplifyPathUpToRoot(target, view.getPathPart());
     if (resolved == null) {
       return null;
diff --git a/java/com/google/gitiles/ViewFilter.java b/java/com/google/gitiles/ViewFilter.java
index dd3d54a..6f124e5 100644
--- a/java/com/google/gitiles/ViewFilter.java
+++ b/java/com/google/gitiles/ViewFilter.java
@@ -22,6 +22,7 @@
 import com.google.gitiles.GitilesRequestFailureException.FailureReason;
 import java.io.IOException;
 import java.util.Map;
+import javax.annotation.Nullable;
 import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
@@ -135,7 +136,7 @@
     return false;
   }
 
-  private GitilesView.Builder parse(HttpServletRequest req) throws IOException {
+  private @Nullable GitilesView.Builder parse(HttpServletRequest req) throws IOException {
     String repoName = trimLeadingSlash(getRegexGroup(req, 1));
     if (repoName.isEmpty()) {
       return GitilesView.hostIndex();
@@ -179,7 +180,7 @@
     return GitilesView.repositoryIndex().setRepositoryName(repoName);
   }
 
-  private GitilesView.Builder parseArchiveCommand(
+  private @Nullable GitilesView.Builder parseArchiveCommand(
       HttpServletRequest req, String repoName, String path) throws IOException {
     String ext = null;
     for (String e : ArchiveFormat.allExtensions()) {
@@ -203,8 +204,8 @@
         .setExtension(ext);
   }
 
-  private GitilesView.Builder parseAutoCommand(HttpServletRequest req, String repoName, String path)
-      throws IOException {
+  private @Nullable GitilesView.Builder parseAutoCommand(
+      HttpServletRequest req, String repoName, String path) throws IOException {
     // Note: if you change the mapping for +, make sure to change
     // GitilesView.toUrl() correspondingly.
     if (path.isEmpty()) {
@@ -227,7 +228,7 @@
     return b;
   }
 
-  private GitilesView.Builder parseBlameCommand(
+  private @Nullable GitilesView.Builder parseBlameCommand(
       HttpServletRequest req, String repoName, String path) throws IOException {
     if (path.isEmpty()) {
       return null;
@@ -242,7 +243,7 @@
         .setPathPart(result.getPath());
   }
 
-  private GitilesView.Builder parseDescribeCommand(String repoName, String path) {
+  private @Nullable GitilesView.Builder parseDescribeCommand(String repoName, String path) {
     if (isEmptyOrSlash(path)) {
       return null;
     }
@@ -254,7 +255,8 @@
     return parseDiffCommand(repoName, parseRevision(req, path));
   }
 
-  private GitilesView.Builder parseDiffCommand(String repoName, RevisionParser.Result result) {
+  private @Nullable GitilesView.Builder parseDiffCommand(
+      String repoName, RevisionParser.Result result) {
     if (result == null) {
       return null;
     }
@@ -265,8 +267,8 @@
         .setPathPart(result.getPath());
   }
 
-  private GitilesView.Builder parseLogCommand(HttpServletRequest req, String repoName, String path)
-      throws IOException {
+  private @Nullable GitilesView.Builder parseLogCommand(
+      HttpServletRequest req, String repoName, String path) throws IOException {
     if (isEmptyOrSlash(path)) {
       return GitilesView.log().setRepositoryName(repoName);
     }
@@ -290,7 +292,8 @@
     return parseShowCommand(repoName, parseRevision(req, path));
   }
 
-  private GitilesView.Builder parseShowCommand(String repoName, RevisionParser.Result result) {
+  private @Nullable GitilesView.Builder parseShowCommand(
+      String repoName, RevisionParser.Result result) {
     if (result == null || result.getOldRevision() != null) {
       return null;
     }
@@ -308,7 +311,8 @@
     return parseDocCommand(repoName, parseRevision(req, path));
   }
 
-  private GitilesView.Builder parseDocCommand(String repoName, RevisionParser.Result result) {
+  private @Nullable GitilesView.Builder parseDocCommand(
+      String repoName, RevisionParser.Result result) {
     if (result == null || result.getOldRevision() != null) {
       return null;
     }
diff --git a/java/com/google/gitiles/blame/BlameServlet.java b/java/com/google/gitiles/blame/BlameServlet.java
index 9dd5e91..179b5d6 100644
--- a/java/com/google/gitiles/blame/BlameServlet.java
+++ b/java/com/google/gitiles/blame/BlameServlet.java
@@ -39,6 +39,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import javax.annotation.Nullable;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
@@ -183,7 +184,7 @@
     return new RegionResult(regions, lastCommitBlobId);
   }
 
-  private static ObjectId resolveBlob(GitilesView view, RevWalk rw, ObjectId commitId)
+  private static @Nullable ObjectId resolveBlob(GitilesView view, RevWalk rw, ObjectId commitId)
       throws IOException {
     try {
       if (commitId == null || Strings.isNullOrEmpty(view.getPathPart())) {
diff --git a/java/com/google/gitiles/doc/DocServlet.java b/java/com/google/gitiles/doc/DocServlet.java
index 4def176..d2ae028 100644
--- a/java/com/google/gitiles/doc/DocServlet.java
+++ b/java/com/google/gitiles/doc/DocServlet.java
@@ -158,7 +158,8 @@
     return h.hash().toString();
   }
 
-  private MarkdownFile findNavbar(RevWalk rw, RevTree root, String path) throws IOException {
+  private @Nullable MarkdownFile findNavbar(RevWalk rw, RevTree root, String path)
+      throws IOException {
     if (!Strings.isNullOrEmpty(path)) {
       // Traverse up the path until we find a NAVBAR_MD.
       StringBuilder pathRemaining = new StringBuilder(path);
@@ -229,8 +230,8 @@
     return MoreObjects.firstNonNull(title, srcFile.path);
   }
 
-  @Nullable
-  private static MarkdownFile findFile(RevWalk rw, RevTree root, String path) throws IOException {
+  private static @Nullable MarkdownFile findFile(RevWalk rw, RevTree root, String path)
+      throws IOException {
     if (Strings.isNullOrEmpty(path)) {
       path = INDEX_MD;
     }
diff --git a/java/com/google/gitiles/doc/GitilesHtmlExtension.java b/java/com/google/gitiles/doc/GitilesHtmlExtension.java
index 2a325b1..a8fc04f 100644
--- a/java/com/google/gitiles/doc/GitilesHtmlExtension.java
+++ b/java/com/google/gitiles/doc/GitilesHtmlExtension.java
@@ -17,6 +17,7 @@
 import com.google.gitiles.doc.html.HtmlBuilder;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import javax.annotation.Nullable;
 import org.commonmark.Extension;
 import org.commonmark.node.AbstractVisitor;
 import org.commonmark.node.HardLineBreak;
@@ -145,7 +146,7 @@
     }
   }
 
-  private static IframeBlock iframe(String html) {
+  private static @Nullable IframeBlock iframe(String html) {
     IframeBlock iframe = new IframeBlock();
     Matcher m = ATTR.matcher(html);
     while (m.find()) {
diff --git a/java/com/google/gitiles/doc/ImageLoader.java b/java/com/google/gitiles/doc/ImageLoader.java
index 81724b6..0a1cc3d 100644
--- a/java/com/google/gitiles/doc/ImageLoader.java
+++ b/java/com/google/gitiles/doc/ImageLoader.java
@@ -57,7 +57,7 @@
     return SoyConstants.IMAGE_URI_INNOCUOUS_OUTPUT;
   }
 
-  private String inlineMaybe(@Nullable String markdownPath, String imagePath) {
+  private @Nullable String inlineMaybe(@Nullable String markdownPath, String imagePath) {
     if (config.imageLimit <= 0) {
       return null;
     }
diff --git a/java/com/google/gitiles/doc/MarkdownToHtml.java b/java/com/google/gitiles/doc/MarkdownToHtml.java
index a2d5752..cb8afae 100644
--- a/java/com/google/gitiles/doc/MarkdownToHtml.java
+++ b/java/com/google/gitiles/doc/MarkdownToHtml.java
@@ -149,7 +149,7 @@
     return html;
   }
 
-  private static ImageLoader newImageLoader(Builder b) {
+  private static @Nullable ImageLoader newImageLoader(Builder b) {
     if (b.reader != null && b.view != null && b.config != null && b.root != null) {
       return new ImageLoader(b.reader, b.view, b.config, b.root);
     }
@@ -170,7 +170,7 @@
   }
 
   /** Render the document AST to sanitized HTML. */
-  public SafeHtml toSoyHtml(Node node) {
+  public @Nullable SafeHtml toSoyHtml(Node node) {
     if (node != null) {
       SoyHtmlBuilder out = new SoyHtmlBuilder();
       renderToHtml(out, node);
diff --git a/java/com/google/gitiles/doc/MarkdownUtil.java b/java/com/google/gitiles/doc/MarkdownUtil.java
index 9a6bb82..b3ce433 100644
--- a/java/com/google/gitiles/doc/MarkdownUtil.java
+++ b/java/com/google/gitiles/doc/MarkdownUtil.java
@@ -16,13 +16,14 @@
 
 import com.google.common.base.CharMatcher;
 import com.google.common.base.Strings;
+import javax.annotation.Nullable;
 import org.commonmark.node.Heading;
 import org.commonmark.node.Node;
 import org.commonmark.node.Text;
 
 class MarkdownUtil {
   /** Combine child nodes as string; this must be escaped for HTML. */
-  static String getInnerText(Node node) {
+  static @Nullable String getInnerText(Node node) {
     if (node == null || node.getFirstChild() == null) {
       return null;
     }
@@ -42,7 +43,7 @@
     }
   }
 
-  static String getTitle(Node node) {
+  static @Nullable String getTitle(Node node) {
     if (node instanceof Heading) {
       if (((Heading) node).getLevel() == 1) {
         return getInnerText(node);
diff --git a/java/com/google/gitiles/doc/Navbar.java b/java/com/google/gitiles/doc/Navbar.java
index 0fc2758..60d1059 100644
--- a/java/com/google/gitiles/doc/Navbar.java
+++ b/java/com/google/gitiles/doc/Navbar.java
@@ -25,6 +25,7 @@
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import javax.annotation.Nullable;
 import org.commonmark.node.Heading;
 import org.commonmark.node.Node;
 import org.eclipse.jgit.util.RawParseUtils;
@@ -75,7 +76,7 @@
     return data;
   }
 
-  private Object logo() {
+  private @Nullable Object logo() {
     if (logoUrl == null) {
       return null;
     }
diff --git a/java/com/google/gitiles/doc/TocFormatter.java b/java/com/google/gitiles/doc/TocFormatter.java
index 6f25f58..297794d 100644
--- a/java/com/google/gitiles/doc/TocFormatter.java
+++ b/java/com/google/gitiles/doc/TocFormatter.java
@@ -25,6 +25,7 @@
 import java.util.Deque;
 import java.util.List;
 import java.util.Map;
+import javax.annotation.Nullable;
 import org.apache.commons.lang3.StringUtils;
 import org.commonmark.node.Heading;
 import org.commonmark.node.Node;
@@ -149,7 +150,7 @@
     }
   }
 
-  private static NamedAnchor findAnchor(Node node) {
+  private static @Nullable NamedAnchor findAnchor(Node node) {
     for (Node c = node.getFirstChild(); c != null; c = c.getNext()) {
       if (c instanceof NamedAnchor) {
         return (NamedAnchor) c;
diff --git a/javatests/com/google/gitiles/LinkifierTest.java b/javatests/com/google/gitiles/LinkifierTest.java
index baa9727..bcd82a4 100644
--- a/javatests/com/google/gitiles/LinkifierTest.java
+++ b/javatests/com/google/gitiles/LinkifierTest.java
@@ -17,6 +17,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import com.google.common.collect.ImmutableMap;
+import javax.annotation.Nullable;
 import javax.servlet.http.HttpServletRequest;
 import org.eclipse.jgit.lib.Config;
 import org.junit.Test;
@@ -68,6 +69,7 @@
     Linkifier l =
         new Linkifier(
             new GitilesUrls() {
+              @Nullable
               @Override
               public String getBaseGerritUrl(HttpServletRequest req) {
                 return null;
diff --git a/javatests/com/google/gitiles/TestGitilesServlet.java b/javatests/com/google/gitiles/TestGitilesServlet.java
index df2be60..b68ea87 100644
--- a/javatests/com/google/gitiles/TestGitilesServlet.java
+++ b/javatests/com/google/gitiles/TestGitilesServlet.java
@@ -18,6 +18,7 @@
 import java.net.URL;
 import java.util.Collections;
 import java.util.Enumeration;
+import javax.annotation.Nullable;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
@@ -90,7 +91,7 @@
     servlet.init(
         new ServletConfig() {
           @Override
-          public String getInitParameter(String name) {
+          public @Nullable String getInitParameter(String name) {
             return null;
           }
 
@@ -100,7 +101,7 @@
           }
 
           @Override
-          public ServletContext getServletContext() {
+          public @Nullable ServletContext getServletContext() {
             return null;
           }