Merge changes from topic "gitiles-source-submodule"

* changes:
  Mark war-provided libraries as neverlink inside the Gerrit tree
  Make webassets packaging repo-path independent
diff --git a/java/com/google/gitiles/Renderer.java b/java/com/google/gitiles/Renderer.java
index c8c1ba6..0087e04 100644
--- a/java/com/google/gitiles/Renderer.java
+++ b/java/com/google/gitiles/Renderer.java
@@ -99,7 +99,7 @@
           .put("gitiles.FAVICON_32_URL", "favicon-32x32.png")
           .put("gitiles.FAVICON_16_URL", "favicon-16x16.png")
           .put("gitiles.APPLE_TOUCH_ICON_URL", "apple-touch-icon.png")
-          .build();
+          .buildOrThrow();
 
   protected static Function<String, URL> fileUrlMapper() {
     return fileUrlMapper("");
@@ -140,7 +140,7 @@
     for (URL u : customTemplates) {
       b.put(u.toString(), u);
     }
-    templates = b.build();
+    templates = b.buildOrThrow();
 
     Map<String, String> allGlobals = Maps.newHashMap();
     for (Map.Entry<String, String> e : STATIC_URL_GLOBALS.entrySet()) {
@@ -152,12 +152,7 @@
   }
 
   public HashCode getTemplateHash(String soyFile) {
-    HashCode h = hashes.get(soyFile);
-    if (h == null) {
-      h = computeTemplateHash(soyFile);
-      hashes.put(soyFile, h);
-    }
-    return h;
+    return hashes.computeIfAbsent(soyFile, this::computeTemplateHash);
   }
 
   HashCode computeTemplateHash(String soyFile) {
@@ -239,8 +234,8 @@
 
       @Override
       public void close() throws IOException {
-        try (OutputStream o = out) {
-          o.write(tail);
+        try (out) {
+          out.write(tail);
         }
       }
     };
@@ -259,7 +254,7 @@
     }
     ImmutableMap.Builder<String, Object> ij =
         ImmutableMap.<String, Object>builder()
-            .put("staticUrls", staticUrls.build())
+            .put("staticUrls", staticUrls.buildOrThrow())
             .put("SITE_TITLE", siteTitle)
             .put("THEME_INIT_SCRIPT", THEME_INIT_SCRIPT)
             .put("THEME_TOGGLE_SCRIPT", THEME_TOGGLE_SCRIPT);
@@ -267,7 +262,7 @@
     if (nonce.isPresent()) {
       ij.put("csp_nonce", nonce.get());
     }
-    return getSauce().renderTemplate(templateName).setIj(ij.build());
+    return getSauce().renderTemplate(templateName).setIj(ij.buildOrThrow());
   }
 
   protected abstract SoySauce getSauce();
diff --git a/java/com/google/gitiles/blame/cache/BlameCache.java b/java/com/google/gitiles/blame/cache/BlameCache.java
index 7cb7bad..2dc7216 100644
--- a/java/com/google/gitiles/blame/cache/BlameCache.java
+++ b/java/com/google/gitiles/blame/cache/BlameCache.java
@@ -20,6 +20,7 @@
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.Repository;
 
+/** Cache for blame information across repositories and commits. */
 public interface BlameCache {
   /**
    * Gets the blame of a path at a given commit.
@@ -33,8 +34,7 @@
    *
    * @return the blame of a path at a given commit.
    */
-  default List<Region> get(
-      Repository repo, ObjectId commitId, String path, Set<ObjectId> ignoreIds)
+  default List<Region> get(Repository repo, ObjectId commitId, String path, Set<ObjectId> ignoreIds)
       throws IOException {
     if (ignoreIds == null || ignoreIds.isEmpty()) {
       return get(repo, commitId, path);
diff --git a/java/com/google/gitiles/blame/cache/BlameCacheImpl.java b/java/com/google/gitiles/blame/cache/BlameCacheImpl.java
index 1bed1c2..44d4617 100644
--- a/java/com/google/gitiles/blame/cache/BlameCacheImpl.java
+++ b/java/com/google/gitiles/blame/cache/BlameCacheImpl.java
@@ -55,6 +55,7 @@
     return builder.weigher((k, v) -> v.size());
   }
 
+  /** Cache key identifying a path at a commit with optional ignored revisions. */
   public static class Key {
     private final ObjectId commitId;
     private final String path;
@@ -84,8 +85,7 @@
 
     @Override
     public boolean equals(Object o) {
-      if (o instanceof Key) {
-        Key k = (Key) o;
+      if (o instanceof Key k) {
         return Objects.equals(commitId, k.commitId)
             && Objects.equals(path, k.path)
             && Objects.equals(ignoreIds, k.ignoreIds);
@@ -125,6 +125,10 @@
     this(defaultBuilder());
   }
 
+  public BlameCacheImpl(CacheBuilder<? super Key, ? super List<Region>> builder) {
+    this.cache = builder.build();
+  }
+
   public Cache<Key, List<Region>> getCache() {
     return cache;
   }
@@ -133,18 +137,13 @@
     return () -> loadBlame(key, repo);
   }
 
-  public BlameCacheImpl(CacheBuilder<? super Key, ? super List<Region>> builder) {
-    this.cache = builder.build();
-  }
-
   @Override
   public List<Region> get(Repository repo, ObjectId commitId, String path) throws IOException {
     return get(repo, commitId, path, ImmutableSet.of());
   }
 
   @Override
-  public List<Region> get(
-      Repository repo, ObjectId commitId, String path, Set<ObjectId> ignoreIds)
+  public List<Region> get(Repository repo, ObjectId commitId, String path, Set<ObjectId> ignoreIds)
       throws IOException {
     try {
       Key key = new Key(commitId, path, ignoreIds);
@@ -202,7 +201,7 @@
     }
   }
 
-  public static List<Region> loadRegions(BlameGenerator gen) throws IOException {
+  public static ImmutableList<Region> loadRegions(BlameGenerator gen) throws IOException {
     Map<ObjectId, PooledCommit> commits = Maps.newHashMap();
     Interner<String> strings = Interners.newStrongInterner();
     int lineCount = gen.getResultContents().size();
@@ -222,8 +221,8 @@
                 new PersonIdent(
                     strings.intern(author.getName()),
                     strings.intern(author.getEmailAddress()),
-                    author.getWhen(),
-                    author.getTimeZone()));
+                    author.getWhenAsInstant(),
+                    author.getZoneId()));
         commits.put(pc.commit, pc);
       }
       path = strings.intern(path);
diff --git a/java/com/google/gitiles/doc/MarkdownConfig.java b/java/com/google/gitiles/doc/MarkdownConfig.java
index d16380a..8490c19 100644
--- a/java/com/google/gitiles/doc/MarkdownConfig.java
+++ b/java/com/google/gitiles/doc/MarkdownConfig.java
@@ -16,11 +16,13 @@
 
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
+import java.util.Objects;
 import java.util.Set;
 import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.Config.SectionParser;
 import org.eclipse.jgit.util.StringUtils;
 
+/** Configuration options for markdown parsing and rendering in Gitiles. */
 public class MarkdownConfig {
   public static final int IMAGE_LIMIT = 256 << 10;
 
@@ -82,7 +84,8 @@
     if (safeHtml) {
       f = cfg.getStringList("markdown", null, "allowiframe");
     }
-    allowAnyIFrame = f.length == 1 && Boolean.TRUE.equals(StringUtils.toBooleanOrNull(f[0]));
+    allowAnyIFrame =
+        f.length == 1 && Objects.equals(StringUtils.toBooleanOrNull(f[0]), Boolean.TRUE);
     if (allowAnyIFrame) {
       allowIFrame = ImmutableList.of();
     } else {
@@ -109,12 +112,12 @@
     toc = on("toc", p.toc, enable, disable);
     mermaid = on("mermaid", p.mermaid, enable, disable);
 
-    allowAnyIFrame = safeHtml ? p.allowAnyIFrame : false;
+    allowAnyIFrame = safeHtml && p.allowAnyIFrame;
     allowIFrame = safeHtml ? p.allowIFrame : ImmutableList.of();
   }
 
   private static boolean on(String key, boolean val, Set<String> enable, Set<String> disable) {
-    return enable.contains(key) ? true : disable.contains(key) ? false : val;
+    return enable.contains(key) || (disable.contains(key) ? false : val);
   }
 
   boolean isIFrameAllowed(String src) {
diff --git a/java/com/google/gitiles/doc/MarkdownToHtml.java b/java/com/google/gitiles/doc/MarkdownToHtml.java
index d36e18b..4afe8b3 100644
--- a/java/com/google/gitiles/doc/MarkdownToHtml.java
+++ b/java/com/google/gitiles/doc/MarkdownToHtml.java
@@ -17,15 +17,19 @@
 import static com.google.gitiles.doc.MarkdownUtil.getInnerText;
 
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Ascii;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.common.html.types.LegacyConversions;
 import com.google.common.html.types.SafeHtml;
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
 import com.google.gitiles.GitilesView;
 import com.google.gitiles.ThreadSafePrettifyParser;
 import com.google.gitiles.doc.html.HtmlBuilder;
 import com.google.gitiles.doc.html.SoyHtmlBuilder;
-import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import javax.annotation.Nullable;
 import org.commonmark.ext.front.matter.YamlFrontMatterBlock;
 import org.commonmark.ext.gfm.strikethrough.Strikethrough;
@@ -76,6 +80,7 @@
     return new Builder();
   }
 
+  /** A builder for {@link MarkdownToHtml}. */
   public static class Builder {
     private String requestUri;
     private GitilesView view;
@@ -87,36 +92,43 @@
 
     Builder() {}
 
+    @CanIgnoreReturnValue
     public Builder setRequestUri(@Nullable String uri) {
       requestUri = uri;
       return this;
     }
 
+    @CanIgnoreReturnValue
     public Builder setGitilesView(@Nullable GitilesView view) {
       this.view = view;
       return this;
     }
 
+    @CanIgnoreReturnValue
     public Builder setConfig(@Nullable MarkdownConfig config) {
       this.config = config;
       return this;
     }
 
+    @CanIgnoreReturnValue
     public Builder setFilePath(@Nullable String filePath) {
       this.filePath = Strings.emptyToNull(filePath);
       return this;
     }
 
+    @CanIgnoreReturnValue
     public Builder setReader(ObjectReader reader) {
       this.reader = reader;
       return this;
     }
 
+    @CanIgnoreReturnValue
     public Builder setRootTree(RevTree tree) {
       this.root = tree;
       return this;
     }
 
+    @CanIgnoreReturnValue
     public Builder setHtmlSanitizer(HtmlSanitizer htmlSanitizer) {
       this.htmlSanitizer = MoreObjects.firstNonNull(htmlSanitizer, HtmlSanitizer.DISABLED);
       return this;
@@ -150,7 +162,8 @@
     return html;
   }
 
-  private static @Nullable ImageLoader newImageLoader(Builder b) {
+  @Nullable
+  private static 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);
     }
@@ -171,7 +184,8 @@
   }
 
   /** Render the document AST to sanitized HTML. */
-  public @Nullable SafeHtml toSoyHtml(Node node) {
+  @Nullable
+  public SafeHtml toSoyHtml(Node node) {
     if (node != null) {
       SoyHtmlBuilder out = new SoyHtmlBuilder();
       renderToHtml(out, node);
@@ -244,11 +258,12 @@
           .close("span")
           .close("a");
       // github markdown compatibility
-      if (!id.equals(id.toLowerCase())) {
+      String lowerId = Ascii.toLowerCase(id);
+      if (!id.equals(lowerId)) {
         html.open("a")
             .attribute("class", "h")
-            .attribute("name", id.toLowerCase())
-            .attribute("href", "#" + id.toLowerCase())
+            .attribute("name", lowerId)
+            .attribute("href", "#" + lowerId)
             .open("span")
             .close("span")
             .close("a");
@@ -275,15 +290,6 @@
     }
   }
 
-  private static boolean isInTightList(Paragraph c) {
-    Block b = c.getParent(); // b is probably a ListItem
-    if (b != null) {
-      Block a = b.getParent();
-      return a instanceof ListBlock && ((ListBlock) a).isTight();
-    }
-    return false;
-  }
-
   @Override
   public void visit(BlockQuote node) {
     wrapChildren("blockquote", node);
@@ -292,8 +298,8 @@
   @Override
   public void visit(OrderedList node) {
     html.open("ol");
-    if (node.getStartNumber() != 1) {
-      html.attribute("start", Integer.toString(node.getStartNumber()));
+    if (node.getMarkerStartNumber() != 1) {
+      html.attribute("start", Integer.toString(node.getMarkerStartNumber()));
     }
     visitChildren(node);
     html.close("ol");
@@ -312,10 +318,10 @@
   @Override
   public void visit(FencedCodeBlock node) {
     if (config != null && config.mermaid && isMermaid(node.getInfo())) {
-      java.util.Optional<String> svg = SimpleMermaidRenderer.renderToSvg(node.getLiteral());
+      Optional<String> svg = SimpleMermaidRenderer.renderToSvg(node.getLiteral());
       if (svg.isPresent()) {
         html.open("div").attribute("class", "mermaid-container");
-        html.append(com.google.common.html.types.LegacyConversions.riskilyAssumeSafeHtml(svg.get()));
+        html.append(LegacyConversions.riskilyAssumeSafeHtml(svg.get()));
         html.close("div");
         return;
       }
@@ -323,15 +329,157 @@
     codeInPre(node.getInfo(), node.getLiteral());
   }
 
-  private static boolean isMermaid(@Nullable String info) {
-    return info != null && "mermaid".equalsIgnoreCase(info.trim());
-  }
-
   @Override
   public void visit(IndentedCodeBlock node) {
     codeInPre(null, node.getLiteral());
   }
 
+  @Override
+  public void visit(Code node) {
+    html.open("code").attribute("class", "code").appendAndEscape(node.getLiteral()).close("code");
+  }
+
+  @Override
+  public void visit(Emphasis node) {
+    wrapChildren("em", node);
+  }
+
+  @Override
+  public void visit(StrongEmphasis node) {
+    wrapChildren("strong", node);
+  }
+
+  @Override
+  public void visit(Link node) {
+    html.open("a")
+        .attribute("href", href(node.getDestination()))
+        .attribute("title", node.getTitle());
+    visitChildren(node);
+    html.close("a");
+  }
+
+  @Override
+  public void visit(LinkReferenceDefinition node) {
+    // Ignored in rendered output
+  }
+
+  @Override
+  public void visit(Image node) {
+    html.open("img")
+        .attribute("src", image(node.getDestination()))
+        .attribute("title", node.getTitle())
+        .attribute("alt", getInnerText(node));
+  }
+
+  public void visit(TableBlock node) {
+    wrapChildren("table", node);
+  }
+
+  private void visit(TableRow node) {
+    wrapChildren("tr", node);
+  }
+
+  private void visit(TableCell cell) {
+    String tag = cell.isHeader() ? "th" : "td";
+    html.open(tag);
+    TableCell.Alignment alignment = cell.getAlignment();
+    if (alignment != null) {
+      html.attribute("align", toHtml(alignment));
+    }
+    visitChildren(cell);
+    html.close(tag);
+  }
+
+  private void visit(SmartQuoted node) {
+    switch (node.getType()) {
+      case DOUBLE -> {
+        html.entity("&ldquo;");
+        visitChildren(node);
+        html.entity("&rdquo;");
+      }
+      case SINGLE -> {
+        html.entity("&lsquo;");
+        visitChildren(node);
+        html.entity("&rsquo;");
+      }
+    }
+  }
+
+  @Override
+  public void visit(Text node) {
+    html.appendAndEscape(node.getLiteral());
+  }
+
+  @Override
+  public void visit(SoftLineBreak node) {
+    html.space();
+  }
+
+  @Override
+  public void visit(HardLineBreak node) {
+    html.open("br");
+  }
+
+  @Override
+  public void visit(ThematicBreak thematicBreak) {
+    html.open("hr");
+  }
+
+  @Override
+  public void visit(HtmlInline node) {
+    // Discard inline HTML, as it's always partial tags.
+  }
+
+  @Override
+  public void visit(HtmlBlock node) {
+    html.append(htmlSanitizer.sanitize(node.getLiteral()));
+  }
+
+  @Override
+  public void visit(CustomNode node) {
+    switch (node) {
+      case NamedAnchor na -> visit(na);
+      case SmartQuoted sq -> visit(sq);
+      case Strikethrough st -> wrapChildren("del", st);
+      case TableBody tb -> wrapChildren("tbody", tb);
+      case TableCell tc -> visit(tc);
+      case TableHead th -> wrapChildren("thead", th);
+      case TableRow tr -> visit(tr);
+      default -> throw new IllegalArgumentException("cannot render " + node.getClass());
+    }
+  }
+
+  @Override
+  public void visit(CustomBlock node) {
+    switch (node) {
+      case BlockNote bn -> visit(bn);
+      case IframeBlock ib -> visit(ib);
+      case MultiColumnBlock mcb -> visit(mcb);
+      case MultiColumnBlock.Column col -> visit(col);
+      case TableBlock tb -> visit(tb);
+      case TocBlock tb -> toc.format();
+      case YamlFrontMatterBlock yfmb -> {
+        // YAML front matter is document metadata: omit the whole block. We
+        // intentionally do not recurse into it, so its YamlFrontMatterNode
+        // children are never visited and need no visit(CustomNode) handling.
+      }
+      default -> throw new IllegalArgumentException("cannot render " + node.getClass());
+    }
+  }
+
+  private static boolean isInTightList(Paragraph c) {
+    Block b = c.getParent(); // b is probably a ListItem
+    if (b != null) {
+      Block a = b.getParent();
+      return a instanceof ListBlock listBlock && listBlock.isTight();
+    }
+    return false;
+  }
+
+  private static boolean isMermaid(@Nullable String info) {
+    return info != null && Ascii.equalsIgnoreCase("mermaid", info.trim());
+  }
+
   private void codeInPre(String lang, String text) {
     html.open("pre").attribute("class", "code");
     text = printLeadingBlankLines(text);
@@ -374,44 +522,15 @@
 
   private List<ParseResult> parse(@Nullable String lang, String text) {
     if (Strings.isNullOrEmpty(lang)) {
-      return Collections.emptyList();
+      return ImmutableList.of();
     }
     try {
       return ThreadSafePrettifyParser.INSTANCE.parse(lang, text);
     } catch (StackOverflowError e) {
-      return Collections.emptyList();
+      return ImmutableList.of();
     }
   }
 
-  @Override
-  public void visit(Code node) {
-    html.open("code").attribute("class", "code").appendAndEscape(node.getLiteral()).close("code");
-  }
-
-  @Override
-  public void visit(Emphasis node) {
-    wrapChildren("em", node);
-  }
-
-  @Override
-  public void visit(StrongEmphasis node) {
-    wrapChildren("strong", node);
-  }
-
-  @Override
-  public void visit(Link node) {
-    html.open("a")
-        .attribute("href", href(node.getDestination()))
-        .attribute("title", node.getTitle());
-    visitChildren(node);
-    html.close("a");
-  }
-
-  @Override
-  public void visit(LinkReferenceDefinition node) {
-    // Ignored in rendered output
-  }
-
   @VisibleForTesting
   String href(String target) {
     if (target.startsWith("#")
@@ -448,14 +567,6 @@
     return PathResolver.relative(requestUri, dest) + anchor;
   }
 
-  @Override
-  public void visit(Image node) {
-    html.open("img")
-        .attribute("src", image(node.getDestination()))
-        .attribute("title", node.getTitle())
-        .attribute("alt", getInnerText(node));
-  }
-
   String image(String dest) {
     if (HtmlBuilder.isValidHttpUri(dest) || HtmlBuilder.isImageDataUri(dest)) {
       return dest;
@@ -465,83 +576,12 @@
     return SoyConstants.IMAGE_URI_INNOCUOUS_OUTPUT;
   }
 
-  public void visit(TableBlock node) {
-    wrapChildren("table", node);
-  }
-
-  private void visit(TableRow node) {
-    wrapChildren("tr", node);
-  }
-
-  private void visit(TableCell cell) {
-    String tag = cell.isHeader() ? "th" : "td";
-    html.open(tag);
-    TableCell.Alignment alignment = cell.getAlignment();
-    if (alignment != null) {
-      html.attribute("align", toHtml(alignment));
-    }
-    visitChildren(cell);
-    html.close(tag);
-  }
-
   private static String toHtml(TableCell.Alignment alignment) {
-    switch (alignment) {
-      case LEFT:
-        return "left";
-      case CENTER:
-        return "center";
-      case RIGHT:
-        return "right";
-      default:
-        throw new IllegalArgumentException("unsupported alignment " + alignment);
-    }
-  }
-
-  private void visit(SmartQuoted node) {
-    switch (node.getType()) {
-      case DOUBLE:
-        html.entity("&ldquo;");
-        visitChildren(node);
-        html.entity("&rdquo;");
-        break;
-      case SINGLE:
-        html.entity("&lsquo;");
-        visitChildren(node);
-        html.entity("&rsquo;");
-        break;
-      default:
-        throw new IllegalArgumentException("unsupported quote " + node.getType());
-    }
-  }
-
-  @Override
-  public void visit(Text node) {
-    html.appendAndEscape(node.getLiteral());
-  }
-
-  @Override
-  public void visit(SoftLineBreak node) {
-    html.space();
-  }
-
-  @Override
-  public void visit(HardLineBreak node) {
-    html.open("br");
-  }
-
-  @Override
-  public void visit(ThematicBreak thematicBreak) {
-    html.open("hr");
-  }
-
-  @Override
-  public void visit(HtmlInline node) {
-    // Discard inline HTML, as it's always partial tags.
-  }
-
-  @Override
-  public void visit(HtmlBlock node) {
-    html.append(htmlSanitizer.sanitize(node.getLiteral()));
+    return switch (alignment) {
+      case LEFT -> "left";
+      case CENTER -> "center";
+      case RIGHT -> "right";
+    };
   }
 
   private void wrapChildren(String tag, Node node) {
@@ -555,48 +595,4 @@
       c.accept(this);
     }
   }
-
-  @Override
-  public void visit(CustomNode node) {
-    if (node instanceof NamedAnchor) {
-      visit((NamedAnchor) node);
-    } else if (node instanceof SmartQuoted) {
-      visit((SmartQuoted) node);
-    } else if (node instanceof Strikethrough) {
-      wrapChildren("del", node);
-    } else if (node instanceof TableBody) {
-      wrapChildren("tbody", node);
-    } else if (node instanceof TableCell) {
-      visit((TableCell) node);
-    } else if (node instanceof TableHead) {
-      wrapChildren("thead", node);
-    } else if (node instanceof TableRow) {
-      visit((TableRow) node);
-    } else {
-      throw new IllegalArgumentException("cannot render " + node.getClass());
-    }
-  }
-
-  @Override
-  public void visit(CustomBlock node) {
-    if (node instanceof BlockNote) {
-      visit((BlockNote) node);
-    } else if (node instanceof IframeBlock) {
-      visit((IframeBlock) node);
-    } else if (node instanceof MultiColumnBlock) {
-      visit((MultiColumnBlock) node);
-    } else if (node instanceof MultiColumnBlock.Column) {
-      visit((MultiColumnBlock.Column) node);
-    } else if (node instanceof TableBlock) {
-      visit((TableBlock) node);
-    } else if (node instanceof TocBlock) {
-      toc.format();
-    } else if (node instanceof YamlFrontMatterBlock) {
-      // YAML front matter is document metadata: omit the whole block. We
-      // intentionally do not recurse into it, so its YamlFrontMatterNode
-      // children are never visited and need no visit(CustomNode) handling.
-    } else {
-      throw new IllegalArgumentException("cannot render " + node.getClass());
-    }
-  }
 }
diff --git a/java/com/google/gitiles/doc/SimpleMermaidRenderer.java b/java/com/google/gitiles/doc/SimpleMermaidRenderer.java
index da7aca5..140fc44 100644
--- a/java/com/google/gitiles/doc/SimpleMermaidRenderer.java
+++ b/java/com/google/gitiles/doc/SimpleMermaidRenderer.java
@@ -14,6 +14,12 @@
 
 package com.google.gitiles.doc;
 
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static com.google.common.base.Strings.nullToEmpty;
+import static com.google.common.primitives.Doubles.max;
+
+import com.google.common.base.Ascii;
+import com.google.common.collect.Iterables;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -25,7 +31,6 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.TreeMap;
@@ -37,11 +42,12 @@
  * Server-side AST parser, layout engine, and SVG renderer for Mermaid flowchart and graph diagrams.
  *
  * <p>Implements a pure streaming character-scanner AST parser without regex splits, hierarchical
- * Sugiyama DAG layout with cycle breaking, crossing reduction, arbitrary nested subgraphs,
- * dynamic edge clearances, bidirectional curved paths, and responsive SVG emission.
+ * Sugiyama DAG layout with cycle breaking, crossing reduction, arbitrary nested subgraphs, dynamic
+ * edge clearances, bidirectional curved paths, and responsive SVG emission.
  */
-public class SimpleMermaidRenderer {
+public final class SimpleMermaidRenderer {
 
+  /** Graph layout flow direction. */
   public enum Direction {
     LR,
     TD,
@@ -50,6 +56,7 @@
     BT
   }
 
+  /** Visual shape of a graph node. */
   public enum NodeShape {
     RECTANGLE,
     ROUNDED,
@@ -62,6 +69,7 @@
     FLAG
   }
 
+  /** Stroke styling of a connecting edge. */
   public enum EdgeStroke {
     SOLID,
     DASHED,
@@ -72,6 +80,7 @@
   // AST Model Objects
   // =========================================================================
 
+  /** A node in the Mermaid diagram. */
   public static class Node {
     public final String id;
     public String label;
@@ -87,8 +96,8 @@
     public Subgraph parentSubgraph;
     public double barycenter = 0;
     public boolean isVirtual = false;
-    public @Nullable String customFill;
-    public @Nullable String customStroke;
+    @Nullable public String customFill;
+    @Nullable public String customStroke;
 
     public Node(String id) {
       this.id = id;
@@ -102,6 +111,7 @@
     }
   }
 
+  /** A logical subgraph or cluster containing nodes and nested subgraphs. */
   public static class Subgraph {
     public final String id;
     public String title;
@@ -115,8 +125,8 @@
     public double y;
     public double width;
     public double height;
-    public @Nullable String customFill;
-    public @Nullable String customStroke;
+    @Nullable public String customFill;
+    @Nullable public String customStroke;
 
     public Subgraph(String id, String title) {
       this.id = id;
@@ -124,6 +134,7 @@
     }
   }
 
+  /** A directional or bidirectional edge between nodes. */
   public static class Edge {
     public final String fromId;
     public final String toId;
@@ -142,6 +153,7 @@
     }
   }
 
+  /** An edge between subgraphs. */
   public static class SubgraphEdge {
     public final String fromSgId;
     public final String toSgId;
@@ -159,6 +171,7 @@
     }
   }
 
+  /** Parsed Mermaid graph structure containing nodes, edges, and subgraphs. */
   public static class MermaidGraph {
     public Direction direction = Direction.TD;
     public final Map<String, Node> nodes = new LinkedHashMap<>();
@@ -184,16 +197,25 @@
       return node;
     }
 
-    public @Nullable Subgraph lookupSubgraph(String name) {
-      if (name == null) return null;
+    @Nullable
+    public Subgraph lookupSubgraph(String name) {
+      if (name == null) {
+        return null;
+      }
       String clean = name.trim();
       Subgraph sg = subgraphsMap.get(clean);
-      if (sg != null) return sg;
+      if (sg != null) {
+        return sg;
+      }
       sg = subgraphsMap.get(stripWhitespace(clean));
-      if (sg != null) return sg;
-      sg = subgraphsMap.get(clean.toLowerCase());
-      if (sg != null) return sg;
-      sg = subgraphsMap.get(stripWhitespace(clean).toLowerCase());
+      if (sg != null) {
+        return sg;
+      }
+      sg = subgraphsMap.get(clean.toLowerCase(Locale.ROOT));
+      if (sg != null) {
+        return sg;
+      }
+      sg = subgraphsMap.get(stripWhitespace(clean).toLowerCase(Locale.ROOT));
       return sg;
     }
   }
@@ -207,7 +229,7 @@
     int pos;
 
     CharScanner(String text) {
-      this.text = text != null ? text : "";
+      this.text = nullToEmpty(text);
       this.pos = 0;
     }
 
@@ -230,8 +252,10 @@
     }
 
     boolean startsWithIgnoreCase(String prefix) {
-      if (text.length() - pos < prefix.length()) return false;
-      return text.substring(pos, pos + prefix.length()).equalsIgnoreCase(prefix);
+      if (text.length() - pos < prefix.length()) {
+        return false;
+      }
+      return Ascii.equalsIgnoreCase(text.substring(pos, pos + prefix.length()), prefix);
     }
 
     void skip(String prefix) {
@@ -282,7 +306,9 @@
     void skipLine() {
       while (!isEof()) {
         char c = text.charAt(pos++);
-        if (c == '\n') break;
+        if (c == '\n') {
+          break;
+        }
       }
     }
 
@@ -352,7 +378,7 @@
     }
 
     Optional<MermaidGraph> graphOpt = parse(mermaidCode);
-    if (!graphOpt.isPresent()) {
+    if (graphOpt.isEmpty()) {
       return Optional.empty();
     }
 
@@ -373,7 +399,9 @@
     // Scan for diagram type and direction
     while (!s.isEof()) {
       s.skipWhitespaceAndNewlines();
-      if (s.isEof()) break;
+      if (s.isEof()) {
+        break;
+      }
 
       if (s.startsWith("%%")) {
         s.skipLine();
@@ -382,7 +410,7 @@
 
       if (s.tryConsumeIgnoreCase("graph") || s.tryConsumeIgnoreCase("flowchart")) {
         s.skipWhitespace();
-        String dirStr = s.scanIdentifier().toUpperCase();
+        String dirStr = s.scanIdentifier().toUpperCase(Locale.ROOT);
         try {
           if (!dirStr.isEmpty()) {
             graph.direction = Direction.valueOf(dirStr);
@@ -421,7 +449,9 @@
     // Parse diagram statements into AST
     while (!s.isEof()) {
       s.skipWhitespaceAndNewlines();
-      if (s.isEof()) break;
+      if (s.isEof()) {
+        break;
+      }
 
       if (s.startsWith("%%")) {
         s.skipLine();
@@ -451,7 +481,7 @@
 
       if (s.tryConsumeIgnoreCase("direction")) {
         s.skipWhitespace();
-        String dirStr = s.scanIdentifier().toUpperCase();
+        String dirStr = s.scanIdentifier().toUpperCase(Locale.ROOT);
         if (!subgraphStack.isEmpty() && !dirStr.isEmpty()) {
           try {
             subgraphStack.peek().direction = Direction.valueOf(dirStr);
@@ -491,19 +521,26 @@
   private static void parseSubgraphHeader(
       CharScanner s, MermaidGraph graph, Deque<Subgraph> subgraphStack) {
     s.skipWhitespace();
-    String sgId, sgTitle;
+    String sgId;
+    String sgTitle;
 
     // Check for `subgraph "Title Only"`
     if (s.startsWith("\"")) {
       s.skip("\"");
       int start = s.pos;
-      while (!s.isEof() && !s.startsWith("\"")) s.advance();
+      while (!s.isEof() && !s.startsWith("\"")) {
+        s.advance();
+      }
       sgTitle = s.text.substring(start, s.pos);
       s.skip("\"");
       sgId = "sg_" + graph.allSubgraphs.size();
     } else {
       int start = s.pos;
-      while (!s.isEof() && !s.startsWith("[") && !s.startsWith("\"") && s.peek() != '\n' && s.peek() != ';') {
+      while (!s.isEof()
+          && !s.startsWith("[")
+          && !s.startsWith("\"")
+          && s.peek() != '\n'
+          && s.peek() != ';') {
         s.advance();
       }
       String rawName = s.text.substring(start, s.pos).trim();
@@ -514,12 +551,16 @@
         boolean quoted = s.tryConsume("\"");
         int tstart = s.pos;
         if (quoted) {
-          while (!s.isEof() && !s.startsWith("\"]") && !s.startsWith("\"")) s.advance();
+          while (!s.isEof() && !s.startsWith("\"]") && !s.startsWith("\"")) {
+            s.advance();
+          }
           sgTitle = s.text.substring(tstart, s.pos);
           s.skip("\"");
           s.skip("]");
         } else {
-          while (!s.isEof() && !s.startsWith("]")) s.advance();
+          while (!s.isEof() && !s.startsWith("]")) {
+            s.advance();
+          }
           sgTitle = s.text.substring(tstart, s.pos);
           s.skip("]");
         }
@@ -541,8 +582,8 @@
     subgraphStack.push(sg);
     graph.subgraphsMap.put(sgId, sg);
     graph.subgraphsMap.put(sgTitle, sg);
-    graph.subgraphsMap.put(sgId.toLowerCase(), sg);
-    graph.subgraphsMap.put(sgTitle.toLowerCase(), sg);
+    graph.subgraphsMap.put(sgId.toLowerCase(Locale.ROOT), sg);
+    graph.subgraphsMap.put(sgTitle.toLowerCase(Locale.ROOT), sg);
     graph.allSubgraphs.add(sg);
   }
 
@@ -558,7 +599,9 @@
     int start = s.pos;
     while (!s.isEof()) {
       char c = s.peek();
-      if (c == '\n' || c == '\r' || c == ';') break;
+      if (c == '\n' || c == '\r' || c == ';') {
+        break;
+      }
       s.pos++;
     }
     String rest = s.text.substring(start, s.pos);
@@ -579,7 +622,7 @@
       String part = rest.substring(p, nextSep).trim();
       int colonIdx = part.indexOf(':');
       if (colonIdx != -1) {
-        String key = part.substring(0, colonIdx).trim().toLowerCase();
+        String key = part.substring(0, colonIdx).trim().toLowerCase(Locale.ROOT);
         String val = part.substring(colonIdx + 1).trim();
         if (key.equals("fill")) {
           fill = val;
@@ -599,19 +642,29 @@
 
     Subgraph sg = graph.lookupSubgraph(targetId);
     if (sg != null) {
-      if (fill != null) sg.customFill = fill;
-      if (stroke != null) sg.customStroke = stroke;
+      if (fill != null) {
+        sg.customFill = fill;
+      }
+      if (stroke != null) {
+        sg.customStroke = stroke;
+      }
     }
     Node n = graph.nodes.get(targetId);
     if (n != null) {
-      if (fill != null) n.customFill = fill;
-      if (stroke != null) n.customStroke = stroke;
+      if (fill != null) {
+        n.customFill = fill;
+      }
+      if (stroke != null) {
+        n.customStroke = stroke;
+      }
     }
   }
 
   private static boolean isValidCssColor(@Nullable String val) {
-    if (val == null || val.isEmpty()) return false;
-    String v = val.trim().toLowerCase();
+    if (isNullOrEmpty(val)) {
+      return false;
+    }
+    String v = val.trim().toLowerCase(Locale.ROOT);
     if (v.startsWith("javascript:")
         || v.startsWith("data:")
         || v.contains("url(")
@@ -633,7 +686,9 @@
   private static void parseStatement(
       CharScanner s, MermaidGraph graph, @Nullable Subgraph currentSubgraph) {
     List<RawNodeToken> prevGroup = scanNodeGroup(s);
-    if (prevGroup.isEmpty()) return;
+    if (prevGroup.isEmpty()) {
+      return;
+    }
 
     for (RawNodeToken token : prevGroup) {
       applyNodeToken(token, graph, currentSubgraph);
@@ -641,13 +696,19 @@
 
     while (!s.isEof()) {
       char c = s.peek();
-      if (c == ';' || c == '\n' || c == '\r') break;
+      if (c == ';' || c == '\n' || c == '\r') {
+        break;
+      }
 
       RawEdgeToken edge = scanEdgeToken(s);
-      if (edge == null) break;
+      if (edge == null) {
+        break;
+      }
 
       List<RawNodeToken> nextGroup = scanNodeGroup(s);
-      if (nextGroup.isEmpty()) break;
+      if (nextGroup.isEmpty()) {
+        break;
+      }
 
       for (RawNodeToken token : nextGroup) {
         applyNodeToken(token, graph, currentSubgraph);
@@ -687,7 +748,9 @@
   private static List<RawNodeToken> scanNodeGroup(CharScanner s) {
     List<RawNodeToken> group = new ArrayList<>();
     RawNodeToken first = scanNodeToken(s);
-    if (first == null) return group;
+    if (first == null) {
+      return group;
+    }
     group.add(first);
 
     while (!s.isEof()) {
@@ -753,7 +816,7 @@
 
     StringBuilder cur = new StringBuilder();
     for (String w : words) {
-      if (cur.length() == 0) {
+      if (cur.isEmpty()) {
         cur.append(w);
       } else if (cur.length() + 1 + w.length() <= Math.max(targetLen + 4, 18)) {
         cur.append(" ").append(w);
@@ -768,12 +831,17 @@
     return result;
   }
 
-  private static @Nullable RawNodeToken scanNodeToken(CharScanner s) {
+  @Nullable
+  private static RawNodeToken scanNodeToken(CharScanner s) {
     s.skipWhitespace();
-    if (s.isEof()) return null;
+    if (s.isEof()) {
+      return null;
+    }
 
     String id = s.scanIdentifier();
-    if (id.isEmpty()) return null;
+    if (id.isEmpty()) {
+      return null;
+    }
 
     s.skipWhitespace();
     NodeShape shape = NodeShape.RECTANGLE;
@@ -830,9 +898,12 @@
     return new RawNodeToken(id, shape, label != null ? cleanLabel(label) : null);
   }
 
-  private static @Nullable RawEdgeToken scanEdgeToken(CharScanner s) {
+  @Nullable
+  private static RawEdgeToken scanEdgeToken(CharScanner s) {
     s.skipWhitespace();
-    if (s.isEof()) return null;
+    if (s.isEof()) {
+      return null;
+    }
 
     // 1. Infix labels: -- label -->, -- "label" -->, == label ==>, -. label .->, -- label ---
     if ((s.startsWith("-- ") || s.startsWith("--\"") || s.startsWith("--\t"))
@@ -846,7 +917,9 @@
       }
       String label = cleanLabel(s.text.substring(start, s.pos));
       boolean arrow = s.tryConsume("-->");
-      if (!arrow) s.skip("---");
+      if (!arrow) {
+        s.skip("---");
+      }
       return new RawEdgeToken(EdgeStroke.SOLID, arrow, label);
     }
 
@@ -861,7 +934,9 @@
       }
       String label = cleanLabel(s.text.substring(start, s.pos));
       boolean arrow = s.tryConsume("==>");
-      if (!arrow) s.skip("===");
+      if (!arrow) {
+        s.skip("===");
+      }
       return new RawEdgeToken(EdgeStroke.THICK, arrow, label);
     }
 
@@ -874,7 +949,9 @@
       }
       String label = cleanLabel(s.text.substring(start, s.pos));
       boolean arrow = s.tryConsume(".->");
-      if (!arrow) s.skip(".-");
+      if (!arrow) {
+        s.skip(".-");
+      }
       return new RawEdgeToken(EdgeStroke.DASHED, arrow, label);
     }
 
@@ -914,7 +991,9 @@
   }
 
   private static String cleanLabel(String raw) {
-    if (raw == null) return "";
+    if (raw == null) {
+      return "";
+    }
     String s = raw.trim();
     if (s.startsWith("\"") && s.endsWith("\"") && s.length() >= 2) {
       s = s.substring(1, s.length() - 1);
@@ -928,7 +1007,9 @@
   }
 
   private static String stripWhitespace(String s) {
-    if (s == null) return "";
+    if (s == null) {
+      return "";
+    }
     StringBuilder sb = new StringBuilder(s.length());
     for (int i = 0; i < s.length(); i++) {
       char c = s.charAt(i);
@@ -943,7 +1024,7 @@
 
   private static List<String> parseLabelLines(String label) {
     List<String> lines = new ArrayList<>();
-    if (label == null || label.isEmpty()) {
+    if (isNullOrEmpty(label)) {
       lines.add("");
       return lines;
     }
@@ -974,7 +1055,7 @@
         double tw = maxLineLen * 7.5;
         double th = n.labelLines.size() * 18.0;
         n.width = Math.max(90, tw * 1.5 + 36);
-        n.height = Math.max(50, Math.max(th * 2.2 + 24, n.width * 0.65));
+        n.height = max(50, th * 2.2 + 24, n.width * 0.65);
       } else if (n.shape == NodeShape.CYLINDER) {
         n.width = Math.max(80, maxLineLen * 7.5 + 32);
         n.height = Math.max(50, n.labelLines.size() * 18 + 26);
@@ -1064,11 +1145,13 @@
       } else if (!comp.subgraphs.isEmpty()) {
         layoutCompoundComponent(graph, graph.direction, isHorizontal, comp);
       } else {
-        layoutBySugiyamaDAG(isHorizontal, comp.nodes, comp.edges);
+        layoutBySugiyamaDag(isHorizontal, comp.nodes, comp.edges);
       }
 
-      double cMinX = Double.MAX_VALUE, cMinY = Double.MAX_VALUE;
-      double cMaxX = Double.MIN_VALUE, cMaxY = Double.MIN_VALUE;
+      double cMinX = Double.MAX_VALUE;
+      double cMinY = Double.MAX_VALUE;
+      double cMaxX = Double.MIN_VALUE;
+      double cMaxY = Double.MIN_VALUE;
       for (Node n : comp.nodes.values()) {
         cMinX = Math.min(cMinX, n.x);
         cMinY = Math.min(cMinY, n.y);
@@ -1137,8 +1220,10 @@
     }
 
     // Compute bounding box
-    double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE;
-    double maxX = Double.MIN_VALUE, maxY = Double.MIN_VALUE;
+    double minX = Double.MAX_VALUE;
+    double minY = Double.MAX_VALUE;
+    double maxX = Double.MIN_VALUE;
+    double maxY = Double.MIN_VALUE;
 
     for (Node n : graph.nodes.values()) {
       minX = Math.min(minX, n.x);
@@ -1235,10 +1320,8 @@
     return renderSvg(graph, isHorizontal, totalWidth, totalHeight);
   }
 
-  private static void layoutBySugiyamaDAG(
-      boolean isHorizontal,
-      Map<String, Node> allNodes,
-      List<Edge> edges) {
+  private static void layoutBySugiyamaDag(
+      boolean isHorizontal, Map<String, Node> allNodes, List<Edge> edges) {
 
     // 1. Cycle Breaking via DFS
     Map<String, List<Edge>> adj = new HashMap<>();
@@ -1254,7 +1337,7 @@
     Map<String, Integer> color = new HashMap<>();
     for (String id : allNodes.keySet()) {
       if (color.getOrDefault(id, 0) == 0) {
-        findCyclesDFS(id, adj, color);
+        findCyclesDfs(id, adj, color);
       }
     }
 
@@ -1287,7 +1370,9 @@
       int minOutLayer = Integer.MAX_VALUE;
       for (Edge e : edges) {
         if (!e.isBackEdge) {
-          if (e.toId.equals(n.id)) inCount++;
+          if (e.toId.equals(n.id)) {
+            inCount++;
+          }
           if (e.fromId.equals(n.id)) {
             Node dst = allNodes.get(e.toId);
             if (dst != null) {
@@ -1340,7 +1425,9 @@
     for (int l = 1; l <= maxLayer; l++) {
       List<Node> currentLayer = layerMap.get(l);
       List<Node> prevLayer = layerMap.get(l - 1);
-      if (currentLayer == null) continue;
+      if (currentLayer == null) {
+        continue;
+      }
       for (Node n : currentLayer) {
         double sum = 0;
         int count = 0;
@@ -1365,7 +1452,7 @@
               if (e.toId.equals(n.id) && !e.isBackEdge) {
                 Node pred;
                 if (!e.virtualNodes.isEmpty()) {
-                  pred = e.virtualNodes.get(e.virtualNodes.size() - 1);
+                  pred = Iterables.getLast(e.virtualNodes);
                 } else {
                   pred = allNodes.get(e.fromId);
                 }
@@ -1436,8 +1523,7 @@
           }
         }
 
-        for (int i = 0; i < nodes.size(); i++) {
-          Node n = nodes.get(i);
+        for (Node n : nodes) {
           n.x = curX;
           n.y = curY + (maxH - n.height) / 2.0;
           curX += n.width + 32;
@@ -1508,8 +1594,7 @@
           }
         }
 
-        for (int i = 0; i < nodes.size(); i++) {
-          Node n = nodes.get(i);
+        for (Node n : nodes) {
           n.x = curX + (maxW - n.width) / 2.0;
           n.y = curY;
           curY += n.height + 24;
@@ -1534,7 +1619,7 @@
     }
   }
 
-  private static void findCyclesDFS(
+  private static void findCyclesDfs(
       String u, Map<String, List<Edge>> adj, Map<String, Integer> color) {
     color.put(u, 1); // Gray
     List<Edge> uEdges = adj.get(u);
@@ -1545,20 +1630,23 @@
         if (vColor == 1) {
           e.isBackEdge = true;
         } else if (vColor == 0) {
-          findCyclesDFS(v, adj, color);
+          findCyclesDfs(v, adj, color);
         }
       }
     }
     color.put(u, 2); // Black
   }
 
-  private static @Nullable String getSubgraphSampleNodeId(Subgraph sg) {
+  @Nullable
+  private static String getSubgraphSampleNodeId(Subgraph sg) {
     if (!sg.nodes.isEmpty()) {
       return sg.nodes.get(0).id;
     }
     for (Subgraph child : sg.children) {
       String id = getSubgraphSampleNodeId(child);
-      if (id != null) return id;
+      if (id != null) {
+        return id;
+      }
     }
     return null;
   }
@@ -1575,10 +1663,10 @@
 
   private static class LayoutUnit {
     final String id;
-    final @Nullable Subgraph subgraph;
-    final @Nullable Node node;
-    double width;
-    double height;
+    @Nullable final Subgraph subgraph;
+    @Nullable final Node node;
+    final double width;
+    final double height;
     double x;
     double y;
     int layer = 0;
@@ -1601,8 +1689,7 @@
     }
   }
 
-  private static void registerNodesToUnit(
-      Subgraph sg, LayoutUnit u, Map<String, LayoutUnit> map) {
+  private static void registerNodesToUnit(Subgraph sg, LayoutUnit u, Map<String, LayoutUnit> map) {
     for (Node n : sg.nodes) {
       map.put(n.id, u);
     }
@@ -1616,7 +1703,9 @@
       List<LayoutUnit> units,
       Map<String, LayoutUnit> unitMap,
       List<Edge> unitEdges) {
-    if (units.size() <= 1) return;
+    if (units.size() <= 1) {
+      return;
+    }
 
     // 1. Cycle Breaking
     Map<String, List<Edge>> uAdj = new HashMap<>();
@@ -1631,7 +1720,7 @@
     Map<String, Integer> uColor = new HashMap<>();
     for (LayoutUnit u : units) {
       if (uColor.getOrDefault(u.id, 0) == 0) {
-        findCyclesDFS(u.id, uAdj, uColor);
+        findCyclesDfs(u.id, uAdj, uColor);
       }
     }
 
@@ -1666,7 +1755,9 @@
         if (!ue.isBackEdge) {
           LayoutUnit src = unitMap.get(ue.fromId);
           LayoutUnit dst = unitMap.get(ue.toId);
-          if (dst != null && dst.id.equals(u.id) && (src == null || !src.id.equals(u.id))) inCount++;
+          if (dst != null && dst.id.equals(u.id) && (src == null || !src.id.equals(u.id))) {
+            inCount++;
+          }
           if (src != null && src.id.equals(u.id) && dst != null && !dst.id.equals(u.id)) {
             minOutLayer = Math.min(minOutLayer, dst.layer);
           }
@@ -1686,7 +1777,9 @@
     for (int l = 1; l <= maxLayer; l++) {
       List<LayoutUnit> currentLayer = layerMap.get(l);
       List<LayoutUnit> prevLayer = layerMap.get(l - 1);
-      if (currentLayer == null) continue;
+      if (currentLayer == null) {
+        continue;
+      }
       for (LayoutUnit u : currentLayer) {
         double sum = 0;
         int count = 0;
@@ -1869,8 +1962,7 @@
       LayoutUnit u2 = nodeToUnit.get(e.toId);
       if (u1 != null && u2 != null && !u1.id.equals(u2.id)) {
         String key = u1.id + "->" + u2.id;
-        if (!seenUnitEdges.contains(key)) {
-          seenUnitEdges.add(key);
+        if (seenUnitEdges.add(key)) {
           Edge ue = new Edge(u1.id, u2.id, e.label, e.stroke, e.arrow);
           unitEdges.add(ue);
         }
@@ -1886,8 +1978,7 @@
         LayoutUnit u2 = s2Id != null ? nodeToUnit.get(s2Id) : unitMap.get("sg_" + sg2.id);
         if (u1 != null && u2 != null && !u1.id.equals(u2.id)) {
           String key = u1.id + "->" + u2.id;
-          if (!seenUnitEdges.contains(key)) {
-            seenUnitEdges.add(key);
+          if (seenUnitEdges.add(key)) {
             Edge ue = new Edge(u1.id, u2.id, se.label, se.stroke, se.arrow);
             unitEdges.add(ue);
           }
@@ -1983,8 +2074,7 @@
       LayoutUnit u2 = nodeToUnit.get(e.toId);
       if (u1 != null && u2 != null && !u1.id.equals(u2.id)) {
         String key = u1.id + "->" + u2.id;
-        if (!seenUnitEdges.contains(key)) {
-          seenUnitEdges.add(key);
+        if (seenUnitEdges.add(key)) {
           Edge ue = new Edge(u1.id, u2.id, e.label, e.stroke, e.arrow);
           unitEdges.add(ue);
         }
@@ -2000,8 +2090,7 @@
         LayoutUnit u2 = s2Id != null ? nodeToUnit.get(s2Id) : unitMap.get("sg_" + sg2.id);
         if (u1 != null && u2 != null && !u1.id.equals(u2.id)) {
           String key = u1.id + "->" + u2.id;
-          if (!seenUnitEdges.contains(key)) {
-            seenUnitEdges.add(key);
+          if (seenUnitEdges.add(key)) {
             Edge ue = new Edge(u1.id, u2.id, se.label, se.stroke, se.arrow);
             unitEdges.add(ue);
           }
@@ -2013,8 +2102,10 @@
     layoutUnits(isHorizontal, units, unitMap, unitEdges);
 
     // 6. Assign relative coordinates inside sg and compute sg dimensions
-    double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE;
-    double maxX = Double.MIN_VALUE, maxY = Double.MIN_VALUE;
+    double minX = Double.MAX_VALUE;
+    double minY = Double.MAX_VALUE;
+    double maxX = Double.MIN_VALUE;
+    double maxY = Double.MIN_VALUE;
     for (LayoutUnit u : units) {
       minX = Math.min(minX, u.x);
       minY = Math.min(minY, u.y);
@@ -2038,11 +2129,16 @@
     sg.height = (maxY - minY) + padding * 2 + headerH;
   }
 
-  private static @Nullable Subgraph lookupSubgraphInTree(Subgraph root, String id) {
-    if (root.id.equals(id)) return root;
+  @Nullable
+  private static Subgraph lookupSubgraphInTree(Subgraph root, String id) {
+    if (root.id.equals(id)) {
+      return root;
+    }
     for (Subgraph child : root.children) {
       Subgraph res = lookupSubgraphInTree(child, id);
-      if (res != null) return res;
+      if (res != null) {
+        return res;
+      }
     }
     return null;
   }
@@ -2059,10 +2155,13 @@
     }
   }
 
-  private static Direction getSubgraphEffectiveDirection(@Nullable Subgraph sg, Direction fallback) {
+  private static Direction getSubgraphEffectiveDirection(
+      @Nullable Subgraph sg, Direction fallback) {
     Subgraph cur = sg;
     while (cur != null) {
-      if (cur.direction != null) return cur.direction;
+      if (cur.direction != null) {
+        return cur.direction;
+      }
       cur = cur.parent;
     }
     return fallback;
@@ -2073,24 +2172,29 @@
   // =========================================================================
 
   private static String renderSvg(
-      MermaidGraph graph,
-      boolean isHorizontal,
-      double width,
-      double height) {
+      MermaidGraph graph, boolean isHorizontal, double width, double height) {
 
     StringBuilder svg = new StringBuilder(4096);
     svg.append(
-        String.format(Locale.ROOT,
-            "<svg class=\"mermaid-svg\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 %.0f %.0f\" style=\"max-width: %.0fpx; width: 100%%; height: auto;\">\n",
-            width, height, width));
+        String.format(
+            Locale.ROOT,
+            "<svg class=\"mermaid-svg\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 %.0f"
+                + " %.0f\" style=\"max-width: %.0fpx; width: 100%%; height: auto;\">\n",
+            width,
+            height,
+            width));
 
     svg.append("  <defs>\n");
     svg.append(
-        "    <marker id=\"mermaid-arrow\" viewBox=\"0 0 10 10\" refX=\"8\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\">\n");
+        "    <marker id=\"mermaid-arrow\" viewBox=\"0 0 10 10\" refX=\"8\" refY=\"5\""
+            + " markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\">\n");
     svg.append("      <path d=\"M 0 1.5 L 10 5 L 0 8.5 z\" fill=\"#64748b\" />\n");
     svg.append("    </marker>\n");
-    svg.append("    <filter id=\"node-shadow\" x=\"-5%\" y=\"-5%\" width=\"115%\" height=\"120%\">\n");
-    svg.append("      <feDropShadow dx=\"0\" dy=\"1.5\" stdDeviation=\"2\" flood-color=\"#0f172a\" flood-opacity=\"0.06\" />\n");
+    svg.append(
+        "    <filter id=\"node-shadow\" x=\"-5%\" y=\"-5%\" width=\"115%\" height=\"120%\">\n");
+    svg.append(
+        "      <feDropShadow dx=\"0\" dy=\"1.5\" stdDeviation=\"2\" flood-color=\"#0f172a\""
+            + " flood-opacity=\"0.06\" />\n");
     svg.append("    </filter>\n");
     svg.append("  </defs>\n");
 
@@ -2143,14 +2247,25 @@
     String fill = sg.customFill != null ? sg.customFill : (depth % 2 == 0 ? "#fafafa" : "#f8fafc");
     String stroke = sg.customStroke != null ? sg.customStroke : "#cbd5e1";
     svg.append(
-        String.format(Locale.ROOT,
-            "  <rect x=\"%.1f\" y=\"%.1f\" width=\"%.1f\" height=\"%.1f\" rx=\"8\" fill=\"%s\" stroke=\"%s\" stroke-width=\"1.5\" stroke-dasharray=\"4,4\" />\n",
-            sg.x, sg.y, sg.width, sg.height, fill, stroke));
+        String.format(
+            Locale.ROOT,
+            "  <rect x=\"%.1f\" y=\"%.1f\" width=\"%.1f\" height=\"%.1f\" rx=\"8\" fill=\"%s\""
+                + " stroke=\"%s\" stroke-width=\"1.5\" stroke-dasharray=\"4,4\" />\n",
+            sg.x,
+            sg.y,
+            sg.width,
+            sg.height,
+            fill,
+            stroke));
     if (sg.title != null && !sg.title.isEmpty()) {
       svg.append(
-          String.format(Locale.ROOT,
-              "  <text x=\"%.1f\" y=\"%.1f\" font-size=\"12\" font-weight=\"600\" fill=\"#334155\">%s</text>\n",
-              sg.x + 14, sg.y + 18, escapeXml(sg.title)));
+          String.format(
+              Locale.ROOT,
+              "  <text x=\"%.1f\" y=\"%.1f\" font-size=\"12\" font-weight=\"600\""
+                  + " fill=\"#334155\">%s</text>\n",
+              sg.x + 14,
+              sg.y + 18,
+              escapeXml(sg.title)));
     }
   }
 
@@ -2166,67 +2281,168 @@
     String stroke = n.customStroke != null ? n.customStroke : "#64748b";
 
     // Shape Geometry
-    if (n.shape == NodeShape.CIRCLE) {
-      double r = n.width / 2.0;
-      svg.append(
-          String.format(Locale.ROOT,
-              "  <circle cx=\"%.1f\" cy=\"%.1f\" r=\"%.1f\" fill=\"%s\" stroke=\"%s\" stroke-width=\"1.5\" filter=\"url(#node-shadow)\" />\n",
-              n.x + r, n.y + r, r, fill, stroke));
-    } else if (n.shape == NodeShape.DIAMOND) {
-      double cx = n.x + n.width / 2.0;
-      double cy = n.y + n.height / 2.0;
-      svg.append(
-          String.format(Locale.ROOT,
-              "  <polygon points=\"%.1f,%.1f %.1f,%.1f %.1f,%.1f %.1f,%.1f\" fill=\"%s\" stroke=\"%s\" stroke-width=\"1.5\" filter=\"url(#node-shadow)\" />\n",
-              cx, n.y, n.x + n.width, cy, cx, n.y + n.height, n.x, cy, fill, stroke));
-    } else if (n.shape == NodeShape.HEXAGON) {
-      double h2 = n.height / 2.0;
-      double indent = 16;
-      svg.append(
-          String.format(Locale.ROOT,
-              "  <polygon points=\"%.1f,%.1f %.1f,%.1f %.1f,%.1f %.1f,%.1f %.1f,%.1f %.1f,%.1f\" fill=\"%s\" stroke=\"%s\" stroke-width=\"1.5\" filter=\"url(#node-shadow)\" />\n",
-              n.x + indent, n.y,
-              n.x + n.width - indent, n.y,
-              n.x + n.width, n.y + h2,
-              n.x + n.width - indent, n.y + n.height,
-              n.x + indent, n.y + n.height,
-              n.x, n.y + h2, fill, stroke));
-    } else if (n.shape == NodeShape.CYLINDER) {
-      double ry = 7.0;
-      double rxCyl = n.width / 2.0;
-      double h = n.height;
-      svg.append(
-          String.format(Locale.ROOT,
-              "  <path d=\"M %.1f %.1f a %.1f,%.1f 0 1,0 %.1f,0 a %.1f,%.1f 0 1,0 -%.1f,0 l 0,%.1f a %.1f,%.1f 0 0,0 %.1f,0 l 0,-%.1f Z\" fill=\"%s\" stroke=\"%s\" stroke-width=\"1.5\" filter=\"url(#node-shadow)\" />\n",
-              n.x, n.y + ry, rxCyl, ry, n.width, rxCyl, ry, n.width, h - ry * 2, rxCyl, ry, n.width, h - ry * 2, fill, stroke));
-      svg.append(
-          String.format(Locale.ROOT,
-              "  <path d=\"M %.1f %.1f a %.1f,%.1f 0 0,0 %.1f,0\" fill=\"none\" stroke=\"%s\" stroke-width=\"1.5\" />\n",
-              n.x, n.y + ry, rxCyl, ry, n.width, stroke));
-    } else if (n.shape == NodeShape.FLAG) {
-      double notch = 12;
-      svg.append(
-          String.format(Locale.ROOT,
-              "  <polygon points=\"%.1f,%.1f %.1f,%.1f %.1f,%.1f %.1f,%.1f %.1f,%.1f\" fill=\"%s\" stroke=\"%s\" stroke-width=\"1.5\" filter=\"url(#node-shadow)\" />\n",
-              n.x, n.y, n.x + n.width, n.y, n.x + n.width - notch, n.y + n.height / 2.0, n.x + n.width, n.y + n.height, n.x, n.y + n.height, fill, stroke));
-    } else if (n.shape == NodeShape.SUBROUTINE) {
-      svg.append(
-          String.format(Locale.ROOT,
-              "  <rect x=\"%.1f\" y=\"%.1f\" width=\"%.1f\" height=\"%.1f\" rx=\"4\" fill=\"%s\" stroke=\"%s\" stroke-width=\"1.5\" filter=\"url(#node-shadow)\" />\n",
-              n.x, n.y, n.width, n.height, fill, stroke));
-      svg.append(
-          String.format(Locale.ROOT,
-              "  <line x1=\"%.1f\" y1=\"%.1f\" x2=\"%.1f\" y2=\"%.1f\" stroke=\"%s\" stroke-width=\"1.5\" />\n",
-              n.x + 10, n.y, n.x + 10, n.y + n.height, stroke));
-      svg.append(
-          String.format(Locale.ROOT,
-              "  <line x1=\"%.1f\" y1=\"%.1f\" x2=\"%.1f\" y2=\"%.1f\" stroke=\"%s\" stroke-width=\"1.5\" />\n",
-              n.x + n.width - 10, n.y, n.x + n.width - 10, n.y + n.height, stroke));
-    } else {
-      svg.append(
-          String.format(Locale.ROOT,
-              "  <rect x=\"%.1f\" y=\"%.1f\" width=\"%.1f\" height=\"%.1f\" rx=\"%.1f\" fill=\"%s\" stroke=\"%s\" stroke-width=\"1.5\" filter=\"url(#node-shadow)\" />\n",
-              n.x, n.y, n.width, n.height, rx, fill, stroke));
+    switch (n.shape) {
+      case NodeShape.CIRCLE -> {
+        double r = n.width / 2.0;
+        svg.append(
+            String.format(
+                Locale.ROOT,
+                "  <circle cx=\"%.1f\" cy=\"%.1f\" r=\"%.1f\" fill=\"%s\" stroke=\"%s\""
+                    + " stroke-width=\"1.5\" filter=\"url(#node-shadow)\" />\n",
+                n.x + r,
+                n.y + r,
+                r,
+                fill,
+                stroke));
+      }
+      case NodeShape.DIAMOND -> {
+        double cx = n.x + n.width / 2.0;
+        double cy = n.y + n.height / 2.0;
+        svg.append(
+            String.format(
+                Locale.ROOT,
+                "  <polygon points=\"%.1f,%.1f %.1f,%.1f %.1f,%.1f %.1f,%.1f\" fill=\"%s\""
+                    + " stroke=\"%s\" stroke-width=\"1.5\" filter=\"url(#node-shadow)\" />\n",
+                cx,
+                n.y,
+                n.x + n.width,
+                cy,
+                cx,
+                n.y + n.height,
+                n.x,
+                cy,
+                fill,
+                stroke));
+      }
+      case NodeShape.HEXAGON -> {
+        double h2 = n.height / 2.0;
+        double indent = 16;
+        svg.append(
+            String.format(
+                Locale.ROOT,
+                "  <polygon points=\"%.1f,%.1f %.1f,%.1f %.1f,%.1f %.1f,%.1f %.1f,%.1f %.1f,%.1f\""
+                    + " fill=\"%s\" stroke=\"%s\" stroke-width=\"1.5\" filter=\"url(#node-shadow)\""
+                    + " />\n",
+                n.x + indent,
+                n.y,
+                n.x + n.width - indent,
+                n.y,
+                n.x + n.width,
+                n.y + h2,
+                n.x + n.width - indent,
+                n.y + n.height,
+                n.x + indent,
+                n.y + n.height,
+                n.x,
+                n.y + h2,
+                fill,
+                stroke));
+      }
+      case NodeShape.CYLINDER -> {
+        double ry = 7.0;
+        double rxCyl = n.width / 2.0;
+        double h = n.height;
+        svg.append(
+            String.format(
+                Locale.ROOT,
+                "  <path d=\"M %.1f %.1f a %.1f,%.1f 0 1,0 %.1f,0 a %.1f,%.1f 0 1,0 -%.1f,0 l"
+                    + " 0,%.1f a %.1f,%.1f 0 0,0 %.1f,0 l 0,-%.1f Z\" fill=\"%s\" stroke=\"%s\""
+                    + " stroke-width=\"1.5\" filter=\"url(#node-shadow)\" />\n",
+                n.x,
+                n.y + ry,
+                rxCyl,
+                ry,
+                n.width,
+                rxCyl,
+                ry,
+                n.width,
+                h - ry * 2,
+                rxCyl,
+                ry,
+                n.width,
+                h - ry * 2,
+                fill,
+                stroke));
+        svg.append(
+            String.format(
+                Locale.ROOT,
+                "  <path d=\"M %.1f %.1f a %.1f,%.1f 0 0,0 %.1f,0\" fill=\"none\" stroke=\"%s\""
+                    + " stroke-width=\"1.5\" />\n",
+                n.x,
+                n.y + ry,
+                rxCyl,
+                ry,
+                n.width,
+                stroke));
+      }
+      case NodeShape.FLAG -> {
+        double notch = 12;
+        svg.append(
+            String.format(
+                Locale.ROOT,
+                "  <polygon points=\"%.1f,%.1f %.1f,%.1f %.1f,%.1f %.1f,%.1f %.1f,%.1f\""
+                    + " fill=\"%s\" stroke=\"%s\" stroke-width=\"1.5\" filter=\"url(#node-shadow)\""
+                    + " />\n",
+                n.x,
+                n.y,
+                n.x + n.width,
+                n.y,
+                n.x + n.width - notch,
+                n.y + n.height / 2.0,
+                n.x + n.width,
+                n.y + n.height,
+                n.x,
+                n.y + n.height,
+                fill,
+                stroke));
+      }
+      case NodeShape.SUBROUTINE -> {
+        svg.append(
+            String.format(
+                Locale.ROOT,
+                "  <rect x=\"%.1f\" y=\"%.1f\" width=\"%.1f\" height=\"%.1f\" rx=\"4\" fill=\"%s\""
+                    + " stroke=\"%s\" stroke-width=\"1.5\" filter=\"url(#node-shadow)\" />\n",
+                n.x,
+                n.y,
+                n.width,
+                n.height,
+                fill,
+                stroke));
+        svg.append(
+            String.format(
+                Locale.ROOT,
+                "  <line x1=\"%.1f\" y1=\"%.1f\" x2=\"%.1f\" y2=\"%.1f\" stroke=\"%s\""
+                    + " stroke-width=\"1.5\" />\n",
+                n.x + 10,
+                n.y,
+                n.x + 10,
+                n.y + n.height,
+                stroke));
+        svg.append(
+            String.format(
+                Locale.ROOT,
+                "  <line x1=\"%.1f\" y1=\"%.1f\" x2=\"%.1f\" y2=\"%.1f\" stroke=\"%s\""
+                    + " stroke-width=\"1.5\" />\n",
+                n.x + n.width - 10,
+                n.y,
+                n.x + n.width - 10,
+                n.y + n.height,
+                stroke));
+      }
+      case null, default ->
+          svg.append(
+              String.format(
+                  Locale.ROOT,
+                  "  <rect x=\"%.1f\" y=\"%.1f\" width=\"%.1f\" height=\"%.1f\" rx=\"%.1f\""
+                      + " fill=\"%s\" stroke=\"%s\" stroke-width=\"1.5\""
+                      + " filter=\"url(#node-shadow)\" />\n",
+                  n.x,
+                  n.y,
+                  n.width,
+                  n.height,
+                  rx,
+                  fill,
+                  stroke));
     }
 
     // Node Text using structured AST labelLines
@@ -2236,22 +2452,35 @@
 
     if (n.labelLines.size() == 1) {
       svg.append(
-          String.format(Locale.ROOT,
-              "  <text x=\"%.1f\" y=\"%.1f\" font-size=\"12\" font-weight=\"500\" fill=\"#0f172a\" text-anchor=\"middle\" dominant-baseline=\"central\">%s</text>\n",
-              cx, n.y + textYOffset + n.height / 2.0, escapeXml(n.labelLines.get(0).trim())));
+          String.format(
+              Locale.ROOT,
+              "  <text x=\"%.1f\" y=\"%.1f\" font-size=\"12\" font-weight=\"500\" fill=\"#0f172a\""
+                  + " text-anchor=\"middle\" dominant-baseline=\"central\">%s</text>\n",
+              cx,
+              n.y + textYOffset + n.height / 2.0,
+              escapeXml(n.labelLines.get(0).trim())));
     } else {
       svg.append(
-          String.format(Locale.ROOT,
+          String.format(
+              Locale.ROOT,
               "  <text x=\"%.1f\" y=\"%.1f\" font-size=\"12\" text-anchor=\"middle\">\n",
-              cx, startTextY));
+              cx,
+              startTextY));
       for (int i = 0; i < n.labelLines.size(); i++) {
         String weight = i == 0 ? "600" : "400";
         String textColor = i == 0 ? "#0f172a" : "#475569";
         String fontSize = i == 0 ? "12" : "10.5";
         svg.append(
-            String.format(Locale.ROOT,
-                "    <tspan x=\"%.1f\" dy=\"%s\" font-size=\"%s\" font-weight=\"%s\" fill=\"%s\">%s</tspan>\n",
-                cx, i == 0 ? "0" : "16", fontSize, weight, textColor, escapeXml(n.labelLines.get(i).trim())));
+            String.format(
+                Locale.ROOT,
+                "    <tspan x=\"%.1f\" dy=\"%s\" font-size=\"%s\" font-weight=\"%s\""
+                    + " fill=\"%s\">%s</tspan>\n",
+                cx,
+                i == 0 ? "0" : "16",
+                fontSize,
+                weight,
+                textColor,
+                escapeXml(n.labelLines.get(i).trim())));
       }
       svg.append("  </text>\n");
     }
@@ -2269,7 +2498,10 @@
     String strokeWidth = se.stroke == EdgeStroke.THICK ? "2.5" : "1.5";
     String marker = se.arrow ? "marker-end=\"url(#mermaid-arrow)\" " : "";
 
-    double startX, startY, endX, endY;
+    double startX;
+    double startY;
+    double endX;
+    double endY;
     if (isHorizontal) {
       startX = sg1.x + sg1.width;
       startY = sg1.y + sg1.height / 2.0;
@@ -2281,20 +2513,38 @@
       boolean blocked = false;
       double maxBottom = Math.max(sg1.y + sg1.height, sg2.y + sg2.height);
       for (Node n : graph.nodes.values()) {
-        if (n.x >= startX - 10 && n.x + n.width <= endX + 10 && n.y <= maxY && n.y + n.height >= minY) {
+        if (n.x >= startX - 10
+            && n.x + n.width <= endX + 10
+            && n.y <= maxY
+            && n.y + n.height >= minY) {
           blocked = true;
           maxBottom = Math.max(maxBottom, n.y + n.height);
         }
       }
 
       if (blocked) {
-        double labelW = (se.label != null && !se.label.trim().isEmpty()) ? se.label.trim().length() * 6.5 + 12 : 20;
+        double labelW =
+            (se.label != null && !se.label.trim().isEmpty())
+                ? se.label.trim().length() * 6.5 + 12
+                : 20;
         double loopOffset = Math.max(35.0, labelW / 2.0 + 20.0);
         double cpY = maxBottom + loopOffset;
         svg.append(
-            String.format(Locale.ROOT,
-                "  <path d=\"M %.1f %.1f C %.1f %.1f, %.1f %.1f, %.1f %.1f\" fill=\"none\" stroke=\"#64748b\" stroke-width=\"%s\" %s%s/>\n",
-                startX, startY, startX + 20, cpY, endX - 20, cpY, endX, endY, strokeWidth, strokeDash, marker));
+            String.format(
+                Locale.ROOT,
+                "  <path d=\"M %.1f %.1f C %.1f %.1f, %.1f %.1f, %.1f %.1f\" fill=\"none\""
+                    + " stroke=\"#64748b\" stroke-width=\"%s\" %s%s/>\n",
+                startX,
+                startY,
+                startX + 20,
+                cpY,
+                endX - 20,
+                cpY,
+                endX,
+                endY,
+                strokeWidth,
+                strokeDash,
+                marker));
         if (se.label != null && !se.label.trim().isEmpty()) {
           double midX = (startX + endX) / 2.0;
           renderEdgeLabelBadge(svg, midX, cpY, se.label.trim());
@@ -2312,20 +2562,38 @@
       boolean blocked = false;
       double maxRight = Math.max(sg1.x + sg1.width, sg2.x + sg2.width);
       for (Node n : graph.nodes.values()) {
-        if (n.y >= startY - 10 && n.y + n.height <= endY + 10 && n.x <= maxX && n.x + n.width >= minX) {
+        if (n.y >= startY - 10
+            && n.y + n.height <= endY + 10
+            && n.x <= maxX
+            && n.x + n.width >= minX) {
           blocked = true;
           maxRight = Math.max(maxRight, n.x + n.width);
         }
       }
 
       if (blocked) {
-        double labelW = (se.label != null && !se.label.trim().isEmpty()) ? se.label.trim().length() * 6.5 + 12 : 20;
+        double labelW =
+            (se.label != null && !se.label.trim().isEmpty())
+                ? se.label.trim().length() * 6.5 + 12
+                : 20;
         double loopOffset = Math.max(35.0, labelW / 2.0 + 20.0);
         double cpX = maxRight + loopOffset;
         svg.append(
-            String.format(Locale.ROOT,
-                "  <path d=\"M %.1f %.1f C %.1f %.1f, %.1f %.1f, %.1f %.1f\" fill=\"none\" stroke=\"#64748b\" stroke-width=\"%s\" %s%s/>\n",
-                startX, startY, cpX, startY + 20, cpX, endY - 20, endX, endY, strokeWidth, strokeDash, marker));
+            String.format(
+                Locale.ROOT,
+                "  <path d=\"M %.1f %.1f C %.1f %.1f, %.1f %.1f, %.1f %.1f\" fill=\"none\""
+                    + " stroke=\"#64748b\" stroke-width=\"%s\" %s%s/>\n",
+                startX,
+                startY,
+                cpX,
+                startY + 20,
+                cpX,
+                endY - 20,
+                endX,
+                endY,
+                strokeWidth,
+                strokeDash,
+                marker));
         if (se.label != null && !se.label.trim().isEmpty()) {
           double midY = (startY + endY) / 2.0;
           renderEdgeLabelBadge(svg, cpX, midY, se.label.trim());
@@ -2335,9 +2603,17 @@
     }
 
     svg.append(
-        String.format(Locale.ROOT,
-            "  <line x1=\"%.1f\" y1=\"%.1f\" x2=\"%.1f\" y2=\"%.1f\" stroke=\"#64748b\" stroke-width=\"%s\" %s%s/>\n",
-            startX, startY, endX, endY, strokeWidth, strokeDash, marker));
+        String.format(
+            Locale.ROOT,
+            "  <line x1=\"%.1f\" y1=\"%.1f\" x2=\"%.1f\" y2=\"%.1f\" stroke=\"#64748b\""
+                + " stroke-width=\"%s\" %s%s/>\n",
+            startX,
+            startY,
+            endX,
+            endY,
+            strokeWidth,
+            strokeDash,
+            marker));
 
     if (se.label != null && !se.label.trim().isEmpty()) {
       double midX = (startX + endX) / 2.0;
@@ -2347,19 +2623,20 @@
   }
 
   private static void renderEdge(
-      StringBuilder svg,
-      boolean isHorizontal,
-      MermaidGraph graph,
-      Node src,
-      Node dst,
-      Edge e) {
+      StringBuilder svg, boolean isHorizontal, MermaidGraph graph, Node src, Node dst, Edge e) {
 
     String strokeDash = e.stroke == EdgeStroke.DASHED ? "stroke-dasharray=\"4,4\" " : "";
     String strokeWidth = e.stroke == EdgeStroke.THICK ? "2.5" : "1.5";
     String marker = e.arrow ? "marker-end=\"url(#mermaid-arrow)\" " : "";
 
-    double x1, y1, x2, y2;
-    double cp1x, cp1y, cp2x, cp2y;
+    double x1;
+    double y1;
+    double x2;
+    double y2;
+    double cp1x;
+    double cp1y;
+    double cp2x;
+    double cp2y;
 
     if (!isHorizontal) {
       if (src.id.equals(dst.id)) {
@@ -2394,7 +2671,9 @@
           }
         }
         double labelW =
-            (e.label != null && !e.label.trim().isEmpty()) ? (e.label.trim().length() * 6.5 + 16) : 0;
+            (e.label != null && !e.label.trim().isEmpty())
+                ? (e.label.trim().length() * 6.5 + 16)
+                : 0;
         double loopOffset =
             Math.max(45.0, labelW / 2.0 + 36.0) + (maxRight - Math.min(x1, x2)) * 0.4;
         cp1x = maxRight + loopOffset;
@@ -2414,24 +2693,37 @@
         py.add(dst.y);
 
         StringBuilder pathD = new StringBuilder();
-        pathD.append(String.format(Locale.ROOT,"M %.1f %.1f", px.get(0), py.get(0)));
+        pathD.append(String.format(Locale.ROOT, "M %.1f %.1f", px.get(0), py.get(0)));
         for (int i = 0; i < px.size() - 1; i++) {
-          double xA = px.get(i), yA = py.get(i);
-          double xB = px.get(i + 1), yB = py.get(i + 1);
+          double xA = px.get(i);
+          double yA = py.get(i);
+          double xB = px.get(i + 1);
+          double yB = py.get(i + 1);
           double dy = yB - yA;
           pathD.append(
-              String.format(Locale.ROOT,
+              String.format(
+                  Locale.ROOT,
                   " C %.1f %.1f, %.1f %.1f, %.1f %.1f",
-                  xA, yA + dy * 0.5, xB, yB - dy * 0.5, xB, yB));
+                  xA,
+                  yA + dy * 0.5,
+                  xB,
+                  yB - dy * 0.5,
+                  xB,
+                  yB));
         }
         svg.append(
-            String.format(Locale.ROOT,
+            String.format(
+                Locale.ROOT,
                 "  <path d=\"%s\" fill=\"none\" stroke=\"#64748b\" stroke-width=\"%s\" %s%s/>\n",
-                pathD.toString(), strokeWidth, strokeDash, marker));
+                pathD,
+                strokeWidth,
+                strokeDash,
+                marker));
 
         if (e.label != null && !e.label.trim().isEmpty()) {
           Node firstV = e.virtualNodes.get(0);
-          renderEdgeLabelBadge(svg, firstV.x + firstV.width / 2.0, firstV.y + firstV.height / 2.0, e.label.trim());
+          renderEdgeLabelBadge(
+              svg, firstV.x + firstV.width / 2.0, firstV.y + firstV.height / 2.0, e.label.trim());
         }
         return;
       } else {
@@ -2478,8 +2770,7 @@
           }
         }
         double labelH = 18.0;
-        double loopOffset =
-            Math.max(45.0, labelH + 36.0) + (Math.max(y1, y2) - minTop) * 0.4;
+        double loopOffset = Math.max(45.0, labelH + 36.0) + (Math.max(y1, y2) - minTop) * 0.4;
         cp1x = x1;
         cp1y = minTop - loopOffset;
         cp2x = x2;
@@ -2497,24 +2788,37 @@
         py.add(dst.y + dst.height / 2.0);
 
         StringBuilder pathD = new StringBuilder();
-        pathD.append(String.format(Locale.ROOT,"M %.1f %.1f", px.get(0), py.get(0)));
+        pathD.append(String.format(Locale.ROOT, "M %.1f %.1f", px.get(0), py.get(0)));
         for (int i = 0; i < px.size() - 1; i++) {
-          double xA = px.get(i), yA = py.get(i);
-          double xB = px.get(i + 1), yB = py.get(i + 1);
+          double xA = px.get(i);
+          double yA = py.get(i);
+          double xB = px.get(i + 1);
+          double yB = py.get(i + 1);
           double dx = xB - xA;
           pathD.append(
-              String.format(Locale.ROOT,
+              String.format(
+                  Locale.ROOT,
                   " C %.1f %.1f, %.1f %.1f, %.1f %.1f",
-                  xA + dx * 0.5, yA, xB - dx * 0.5, yB, xB, yB));
+                  xA + dx * 0.5,
+                  yA,
+                  xB - dx * 0.5,
+                  yB,
+                  xB,
+                  yB));
         }
         svg.append(
-            String.format(Locale.ROOT,
+            String.format(
+                Locale.ROOT,
                 "  <path d=\"%s\" fill=\"none\" stroke=\"#64748b\" stroke-width=\"%s\" %s%s/>\n",
-                pathD.toString(), strokeWidth, strokeDash, marker));
+                pathD,
+                strokeWidth,
+                strokeDash,
+                marker));
 
         if (e.label != null && !e.label.trim().isEmpty()) {
           Node firstV = e.virtualNodes.get(0);
-          renderEdgeLabelBadge(svg, firstV.x + firstV.width / 2.0, firstV.y + firstV.height / 2.0, e.label.trim());
+          renderEdgeLabelBadge(
+              svg, firstV.x + firstV.width / 2.0, firstV.y + firstV.height / 2.0, e.label.trim());
         }
         return;
       } else {
@@ -2531,9 +2835,21 @@
     }
 
     svg.append(
-        String.format(Locale.ROOT,
-            "  <path d=\"M %.1f %.1f C %.1f %.1f, %.1f %.1f, %.1f %.1f\" fill=\"none\" stroke=\"#64748b\" stroke-width=\"%s\" %s%s/>\n",
-            x1, y1, cp1x, cp1y, cp2x, cp2y, x2, y2, strokeWidth, strokeDash, marker));
+        String.format(
+            Locale.ROOT,
+            "  <path d=\"M %.1f %.1f C %.1f %.1f, %.1f %.1f, %.1f %.1f\" fill=\"none\""
+                + " stroke=\"#64748b\" stroke-width=\"%s\" %s%s/>\n",
+            x1,
+            y1,
+            cp1x,
+            cp1y,
+            cp2x,
+            cp2y,
+            x2,
+            y2,
+            strokeWidth,
+            strokeDash,
+            marker));
 
     if (e.label != null && !e.label.trim().isEmpty()) {
       // Evaluate Cubic Bézier midpoint at t = 0.5
@@ -2543,22 +2859,34 @@
     }
   }
 
-  private static void renderEdgeLabelBadge(StringBuilder svg, double midX, double midY, String label) {
+  private static void renderEdgeLabelBadge(
+      StringBuilder svg, double midX, double midY, String label) {
     double textLen = label.length() * 6.5;
     double rectW = textLen + 12;
     double rectH = 18;
     svg.append(
-        String.format(Locale.ROOT,
-            "  <rect x=\"%.1f\" y=\"%.1f\" width=\"%.1f\" height=\"%.1f\" rx=\"3\" fill=\"#ffffff\" fill-opacity=\"0.95\" />\n",
-            midX - rectW / 2.0, midY - rectH / 2.0, rectW, rectH));
+        String.format(
+            Locale.ROOT,
+            "  <rect x=\"%.1f\" y=\"%.1f\" width=\"%.1f\" height=\"%.1f\" rx=\"3\" fill=\"#ffffff\""
+                + " fill-opacity=\"0.95\" />\n",
+            midX - rectW / 2.0,
+            midY - rectH / 2.0,
+            rectW,
+            rectH));
     svg.append(
-        String.format(Locale.ROOT,
-            "  <text x=\"%.1f\" y=\"%.1f\" font-size=\"10.5\" fill=\"#475569\" text-anchor=\"middle\" dominant-baseline=\"central\">%s</text>\n",
-            midX, midY, escapeXml(label)));
+        String.format(
+            Locale.ROOT,
+            "  <text x=\"%.1f\" y=\"%.1f\" font-size=\"10.5\" fill=\"#475569\""
+                + " text-anchor=\"middle\" dominant-baseline=\"central\">%s</text>\n",
+            midX,
+            midY,
+            escapeXml(label)));
   }
 
   private static String escapeXml(String text) {
-    if (text == null) return "";
+    if (text == null) {
+      return "";
+    }
     StringBuilder sb = new StringBuilder(text.length() + 16);
     for (int i = 0; i < text.length(); i++) {
       char c = text.charAt(i);
@@ -2567,24 +2895,12 @@
         continue;
       }
       switch (c) {
-        case '&':
-          sb.append("&amp;");
-          break;
-        case '<':
-          sb.append("&lt;");
-          break;
-        case '>':
-          sb.append("&gt;");
-          break;
-        case '"':
-          sb.append("&quot;");
-          break;
-        case '\'':
-          sb.append("&apos;");
-          break;
-        default:
-          sb.append(c);
-          break;
+        case '&' -> sb.append("&amp;");
+        case '<' -> sb.append("&lt;");
+        case '>' -> sb.append("&gt;");
+        case '"' -> sb.append("&quot;");
+        case '\'' -> sb.append("&apos;");
+        default -> sb.append(c);
       }
     }
     return sb.toString();
@@ -2622,7 +2938,9 @@
     double headerH = 22;
 
     for (Subgraph sg : subgraphs) {
-      if (sg.nodes.isEmpty()) continue;
+      if (sg.nodes.isEmpty()) {
+        continue;
+      }
       if (!isHorizontal) {
         double maxW = 0;
         for (Node n : sg.nodes) {
@@ -2656,4 +2974,6 @@
       }
     }
   }
+
+  private SimpleMermaidRenderer() {}
 }
diff --git a/javatests/com/google/gitiles/blame/cache/BlameCacheTest.java b/javatests/com/google/gitiles/blame/cache/BlameCacheTest.java
index 10ff25d..5138ab4 100644
--- a/javatests/com/google/gitiles/blame/cache/BlameCacheTest.java
+++ b/javatests/com/google/gitiles/blame/cache/BlameCacheTest.java
@@ -19,9 +19,7 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
-import java.io.IOException;
 import java.util.List;
-import java.util.Set;
 import org.eclipse.jgit.internal.storage.dfs.DfsRepository;
 import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
 import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
@@ -77,8 +75,7 @@
     BlameCacheImpl.Key kNoIgnore = new BlameCacheImpl.Key(c1, "foo.txt");
     assertThat(kNoIgnore.toString()).isEqualTo("1111111111111111111111111111111111111111:foo.txt");
 
-    BlameCacheImpl.Key kWithIgnore =
-        new BlameCacheImpl.Key(c1, "foo.txt", ImmutableSet.of(c3, c2));
+    BlameCacheImpl.Key kWithIgnore = new BlameCacheImpl.Key(c1, "foo.txt", ImmutableSet.of(c3, c2));
     assertThat(kWithIgnore.toString())
         .isEqualTo(
             "1111111111111111111111111111111111111111:foo.txt"
@@ -105,8 +102,7 @@
     RevCommit c2 =
         repo.commit().parent(c1).add("foo.txt", "line1_formatted\nline2_formatted\n").create();
 
-    List<Region> regions =
-        blameCache.get(repo.getRepository(), c2, "foo.txt", ImmutableSet.of(c2));
+    List<Region> regions = blameCache.get(repo.getRepository(), c2, "foo.txt", ImmutableSet.of(c2));
     assertThat(regions).hasSize(1);
     assertThat(regions.get(0).getSourceCommit()).isEqualTo(c1);
     assertThat(regions.get(0).getStart()).isEqualTo(0);
@@ -124,8 +120,7 @@
     assertThat(unignored.get(0).getSourceCommit()).isEqualTo(c2);
 
     // Query 2: ignored blame
-    List<Region> ignored =
-        blameCache.get(repo.getRepository(), c2, "foo.txt", ImmutableSet.of(c2));
+    List<Region> ignored = blameCache.get(repo.getRepository(), c2, "foo.txt", ImmutableSet.of(c2));
     assertThat(ignored.get(0).getSourceCommit()).isEqualTo(c1);
 
     // Verify both are cached under separate keys
@@ -157,7 +152,7 @@
     BlameCache customCache =
         new BlameCache() {
           @Override
-          public List<Region> get(Repository repo, ObjectId commitId, String path) {
+          public ImmutableList<Region> get(Repository repo, ObjectId commitId, String path) {
             return ImmutableList.of(new Region(null, null, null, 0, 1));
           }
 
@@ -176,13 +171,11 @@
     assertThat(res2).hasSize(1);
 
     // When ignoreIds is non-empty, default method throws UnsupportedOperationException
+    DfsRepository repo2 = repo.getRepository();
+    ObjectId commitId = ObjectId.zeroId();
+    ImmutableSet<ObjectId> ignoreIds = ImmutableSet.of(ObjectId.zeroId());
     assertThrows(
         UnsupportedOperationException.class,
-        () ->
-            customCache.get(
-                repo.getRepository(),
-                ObjectId.zeroId(),
-                "foo.txt",
-                ImmutableSet.of(ObjectId.zeroId())));
+        () -> customCache.get(repo2, commitId, "foo.txt", ignoreIds));
   }
 }
diff --git a/javatests/com/google/gitiles/doc/DocServletTest.java b/javatests/com/google/gitiles/doc/DocServletTest.java
index 27e827f..dcbeeb2 100644
--- a/javatests/com/google/gitiles/doc/DocServletTest.java
+++ b/javatests/com/google/gitiles/doc/DocServletTest.java
@@ -41,14 +41,16 @@
   @Test
   public void includesNavbar() throws Exception {
     String navbar =
-        "# Site Title\n"
-            + "\n"
-            + "[home]: index.md\n"
-            + "[logo]: logo.png\n"
-            + "\n"
-            + "* [Home][home]\n"
-            + "* [README](README.md)\n"
-            + "[extensions]: blocknote\n";
+        """
+        # Site Title
+
+        [home]: index.md
+        [logo]: logo.png
+
+        * [Home][home]
+        * [README](README.md)
+        [extensions]: blocknote
+        """;
     repo.branch("master")
         .commit()
         .add("README.md", "# page\n\nof information.")
@@ -109,11 +111,13 @@
   @Test
   public void dropsHtml() throws Exception {
     String markdown =
-        "# B. Ad\n"
-            + "\n"
-            + "<script>window.alert();</script>\n"
-            + "\n"
-            + "Non-HTML <b>is fine</b>.";
+        """
+        # B. Ad
+
+        <script>window.alert();</script>
+
+        Non-HTML <b>is fine</b>.\
+        """;
     repo.branch("master").commit().add("index.md", markdown).create();
 
     String html = buildHtml("/repo/+doc/master/");
@@ -126,7 +130,11 @@
 
   @Test
   public void namedAnchor() throws Exception {
-    String markdown = "# Section {#debug}\n" + "# Other <a name=\"OLD-SCHOOL\"></a>\n";
+    String markdown =
+        """
+        # Section {#debug}
+        # Other <a name="OLD-SCHOOL"></a>
+        """;
     repo.branch("master").commit().add("index.md", markdown).create();
     String html = buildHtml("/repo/+doc/master/");
     assertThat(html)
@@ -154,7 +162,15 @@
   @Test
   public void noteInList() throws Exception {
     String markdown =
-        "+ one\n\n" + "    ***aside\n" + "    remember this\n" + "    ***\n" + "\n" + "+ two\n";
+        """
+        + one
+
+            ***aside
+            remember this
+            ***
+
+        + two
+        """;
     repo.branch("master").commit().add("index.md", markdown).create();
 
     String html = buildHtml("/repo/+/master/index.md");
diff --git a/javatests/com/google/gitiles/doc/GitilesMarkdownTest.java b/javatests/com/google/gitiles/doc/GitilesMarkdownTest.java
index 2e51b5f..73430ce 100644
--- a/javatests/com/google/gitiles/doc/GitilesMarkdownTest.java
+++ b/javatests/com/google/gitiles/doc/GitilesMarkdownTest.java
@@ -16,6 +16,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import com.google.common.collect.ImmutableSet;
 import com.google.common.html.types.SafeHtml;
 import com.google.gitiles.GitilesView;
 import org.commonmark.node.Node;
@@ -47,16 +48,18 @@
     // are never visited: rendering neither throws (as it would for an unhandled
     // CustomNode) nor leaks the metadata.
     String markdown =
-        "---\n"
-            + "title: Kittens\n"
-            + "tags:\n"
-            + "  - cats\n"
-            + "  - fluffy\n"
-            + "---\n"
-            + "\n"
-            + "# Heading\n"
-            + "\n"
-            + "Body text.\n";
+        """
+        ---
+        title: Kittens
+        tags:
+          - cats
+          - fluffy
+        ---
+
+        # Heading
+
+        Body text.
+        """;
     String html = render(markdown, /* frontMatter= */ true);
     assertThat(html).doesNotContain("Kittens");
     assertThat(html).doesNotContain("cats");
@@ -77,26 +80,24 @@
   @Test
   public void renderMermaidDiagram() {
     String md =
-        "```mermaid\n"
-            + "graph LR\n"
-            + "    subgraph CoreGarden\n"
-            + "        A[\"Fluffy Puppy\"]\n"
-            + "    end\n"
-            + "    subgraph GreenLawn\n"
-            + "        B[\"Playful Kitten\"]\n"
-            + "    end\n"
-            + "    B --> A\n"
-            + "```\n";
+        """
+        ```mermaid
+        graph LR
+            subgraph CoreGarden
+                A["Fluffy Puppy"]
+            end
+            subgraph GreenLawn
+                B["Playful Kitten"]
+            end
+            B --> A
+        ```
+        """;
     Config cfg = new Config();
     cfg.setBoolean("markdown", null, "mermaid", true);
     MarkdownConfig mc = new MarkdownConfig(cfg);
     Node node = GitilesMarkdown.parse(mc, md);
     SafeHtml html =
-        MarkdownToHtml.builder()
-            .setConfig(mc)
-            .setFilePath("index.md")
-            .build()
-            .toSoyHtml(node);
+        MarkdownToHtml.builder().setConfig(mc).setFilePath("index.md").build().toSoyHtml(node);
     assertThat(html).isNotNull();
     String htmlStr = html.getSafeHtmlString();
     assertThat(htmlStr).contains("class=\"mermaid-container\"");
@@ -108,32 +109,30 @@
   @Test
   public void renderMermaidWithSubgraphAndDAG() {
     String md =
-        "```mermaid\n"
-            + "graph TD\n"
-            + "    ClientApp[Little Puppy Plays] --> Extras(Sweet Kitten)\n"
-            + "    ClientApp --> Utils(Happy Bunny)\n"
-            + "    Utils --> ServiceDiscovery[Red Apple Berry]\n"
-            + "    Utils --> ModelManager[Yellow Banana Snack]\n"
-            + "    Extras --> Recognition(Fluffy Duckling)\n"
-            + "    Recognition --> SODA(Green Frog Jump)\n"
-            + "    Recognition --> S3(Sunny Daisy Flower)\n"
-            + "    subgraph Play Park Garden\n"
-            + "        Executors(Teddy Bear)\n"
-            + "        Errors(Wooden Blocks)\n"
-            + "        Protos(Toy Wagon)\n"
-            + "    end\n"
-            + "    Recognition -.-> PlayParkGarden\n"
-            + "```\n";
+        """
+        ```mermaid
+        graph TD
+            ClientApp[Little Puppy Plays] --> Extras(Sweet Kitten)
+            ClientApp --> Utils(Happy Bunny)
+            Utils --> ServiceDiscovery[Red Apple Berry]
+            Utils --> ModelManager[Yellow Banana Snack]
+            Extras --> Recognition(Fluffy Duckling)
+            Recognition --> SODA(Green Frog Jump)
+            Recognition --> S3(Sunny Daisy Flower)
+            subgraph Play Park Garden
+                Executors(Teddy Bear)
+                Errors(Wooden Blocks)
+                Protos(Toy Wagon)
+            end
+            Recognition -.-> PlayParkGarden
+        ```
+        """;
     Config cfg = new Config();
     cfg.setBoolean("markdown", null, "mermaid", true);
     MarkdownConfig mc = new MarkdownConfig(cfg);
     Node node = GitilesMarkdown.parse(mc, md);
     SafeHtml html =
-        MarkdownToHtml.builder()
-            .setConfig(mc)
-            .setFilePath("index.md")
-            .build()
-            .toSoyHtml(node);
+        MarkdownToHtml.builder().setConfig(mc).setFilePath("index.md").build().toSoyHtml(node);
     assertThat(html).isNotNull();
     String htmlStr = html.getSafeHtmlString();
     assertThat(htmlStr).contains("Play Park Garden");
@@ -148,32 +147,30 @@
   @Test
   public void renderMermaidWithQuotedBracketsAndDiamond() {
     String md =
-        "```mermaid\n"
-            + "graph TD\n"
-            + "    A[\"Happy little bunny jumps\"]\n"
-            + "    B[\"Locate [TeddyBear] in garden\"]\n"
-            + "    A --> B\n"
-            + "    B --> C[\"Sing Sweet Melody\"]\n"
-            + "    C --> D[\"Dance Around Blossom Tree\"]\n"
-            + "    E{\"Is kitten happy & pure?\"}\n"
-            + "    E -- Yes --> F[\"Give Tasty Cookie Treat\"]\n"
-            + "    F --> G[\"Play With Soft Yarn Ball\"]\n"
-            + "    E -- No --> H[\"Read Gentle Story Book\"]\n"
-            + "    H --> I[\"Warm Cozy Blanket Nap\"]\n"
-            + "    G --> J[\"Wake Up In Morning Sun\"]\n"
-            + "    I --> J\n"
-            + "    J --> K[\"Smile At Rainbow Sky\"]\n"
-            + "```\n";
+        """
+        ```mermaid
+        graph TD
+            A["Happy little bunny jumps"]
+            B["Locate [TeddyBear] in garden"]
+            A --> B
+            B --> C["Sing Sweet Melody"]
+            C --> D["Dance Around Blossom Tree"]
+            E{"Is kitten happy & pure?"}
+            E -- Yes --> F["Give Tasty Cookie Treat"]
+            F --> G["Play With Soft Yarn Ball"]
+            E -- No --> H["Read Gentle Story Book"]
+            H --> I["Warm Cozy Blanket Nap"]
+            G --> J["Wake Up In Morning Sun"]
+            I --> J
+            J --> K["Smile At Rainbow Sky"]
+        ```
+        """;
     Config cfg = new Config();
     cfg.setBoolean("markdown", null, "mermaid", true);
     MarkdownConfig mc = new MarkdownConfig(cfg);
     Node node = GitilesMarkdown.parse(mc, md);
     SafeHtml html =
-        MarkdownToHtml.builder()
-            .setConfig(mc)
-            .setFilePath("index.md")
-            .build()
-            .toSoyHtml(node);
+        MarkdownToHtml.builder().setConfig(mc).setFilePath("index.md").build().toSoyHtml(node);
     assertThat(html).isNotNull();
     String htmlStr = html.getSafeHtmlString();
     assertThat(htmlStr).contains("Is kitten happy &amp;");
@@ -183,26 +180,24 @@
   @Test
   public void renderMermaidWithBidirectionalEdges() {
     String md =
-        "```mermaid\n"
-            + "graph TD\n"
-            + "    Puppy[\"Fluffy Puppy\"]\n"
-            + "    Kitten[\"Playful Kitten\"]\n"
-            + "    Bunny[\"Little Bunny\"]\n"
-            + "    Puppy -->|Roll Ball| Kitten\n"
-            + "    Kitten -->|Chase Toy| Bunny\n"
-            + "    Bunny -->|Share Snack| Kitten\n"
-            + "    Kitten -->|Give Hug| Puppy\n"
-            + "```\n";
+        """
+        ```mermaid
+        graph TD
+            Puppy["Fluffy Puppy"]
+            Kitten["Playful Kitten"]
+            Bunny["Little Bunny"]
+            Puppy -->|Roll Ball| Kitten
+            Kitten -->|Chase Toy| Bunny
+            Bunny -->|Share Snack| Kitten
+            Kitten -->|Give Hug| Puppy
+        ```
+        """;
     Config cfg = new Config();
     cfg.setBoolean("markdown", null, "mermaid", true);
     MarkdownConfig mc = new MarkdownConfig(cfg);
     Node node = GitilesMarkdown.parse(mc, md);
     SafeHtml html =
-        MarkdownToHtml.builder()
-            .setConfig(mc)
-            .setFilePath("index.md")
-            .build()
-            .toSoyHtml(node);
+        MarkdownToHtml.builder().setConfig(mc).setFilePath("index.md").build().toSoyHtml(node);
     assertThat(html).isNotNull();
     String htmlStr = html.getSafeHtmlString();
     assertThat(htmlStr).contains("Fluffy Puppy");
@@ -226,9 +221,8 @@
     MarkdownConfig anyMc = new MarkdownConfig(anyCfg);
     assertThat(anyMc.isIFrameAllowed("https://anything.com")).isTrue();
 
-    MarkdownConfig copied = mc.copyWithExtensions(
-        java.util.Collections.singleton("toc"),
-        java.util.Collections.singleton("autolink"));
+    MarkdownConfig copied =
+        mc.copyWithExtensions(ImmutableSet.of("toc"), ImmutableSet.of("autolink"));
     assertThat(copied).isNotNull();
   }
 
@@ -240,11 +234,7 @@
     MarkdownConfig mc = new MarkdownConfig(cfg);
     Node node = GitilesMarkdown.parse(mc, md);
     SafeHtml html =
-        MarkdownToHtml.builder()
-            .setConfig(mc)
-            .setFilePath("index.md")
-            .build()
-            .toSoyHtml(node);
+        MarkdownToHtml.builder().setConfig(mc).setFilePath("index.md").build().toSoyHtml(node);
     assertThat(html).isNotNull();
     String htmlStr = html.getSafeHtmlString();
     // When disabled, it renders as a code pre block, not a mermaid svg container
@@ -256,28 +246,27 @@
   @Test
   public void testSecurityMermaidMarkdownEndToEndNoScriptOrIframeInjection() {
     String md =
-        "# Diagram Title\n\n"
-            + "```mermaid\n"
-            + "graph TD\n"
-            + "  A[\"<script>alert('xss-1')</script>\"]\n"
-            + "  B[\"<iframe src='javascript:alert(2)'></iframe>\"]\n"
-            + "  C[\"<img src=x onerror=alert('xss-3')>\"]\n"
-            + "  D[\"<foreignObject><iframe src='https://evil.com'></iframe></foreignObject>\"]\n"
-            + "  A -->|\"<script>alert('edge')</script>\"| B\n"
-            + "  B --> C --> D\n"
-            + "  click A href \"javascript:alert('click')\"\n"
-            + "```\n";
+        """
+        # Diagram Title
+
+        ```mermaid
+        graph TD
+          A["<script>alert('xss-1')</script>"]
+          B["<iframe src='javascript:alert(2)'></iframe>"]
+          C["<img src=x onerror=alert('xss-3')>"]
+          D["<foreignObject><iframe src='https://evil.com'></iframe></foreignObject>"]
+          A -->|"<script>alert('edge')</script>"| B
+          B --> C --> D
+          click A href "javascript:alert('click')"
+        ```
+        """;
 
     Config cfg = new Config();
     cfg.setBoolean("markdown", null, "mermaid", true);
     MarkdownConfig mc = new MarkdownConfig(cfg);
     Node node = GitilesMarkdown.parse(mc, md);
     SafeHtml html =
-        MarkdownToHtml.builder()
-            .setConfig(mc)
-            .setFilePath("index.md")
-            .build()
-            .toSoyHtml(node);
+        MarkdownToHtml.builder().setConfig(mc).setFilePath("index.md").build().toSoyHtml(node);
 
     assertThat(html).isNotNull();
     String htmlStr = html.getSafeHtmlString();
@@ -295,7 +284,8 @@
 
     // Verify payload is safely escaped as XML text inside SVG tspans
     assertThat(htmlStr).contains("&lt;script&gt;alert(&apos;xss-1&apos;)&lt;/script&gt;");
-    assertThat(htmlStr).contains("&lt;iframe src=&apos;javascript:alert(2)&apos;&gt;&lt;/iframe&gt;");
+    assertThat(htmlStr)
+        .contains("&lt;iframe src=&apos;javascript:alert(2)&apos;&gt;&lt;/iframe&gt;");
     assertThat(htmlStr).contains("&lt;img src=x onerror=alert(&apos;xss-3&apos;)&gt;");
   }
 
diff --git a/javatests/com/google/gitiles/doc/SimpleMermaidRendererSecurityTest.java b/javatests/com/google/gitiles/doc/SimpleMermaidRendererSecurityTest.java
index ecaa1e3..29972f6 100644
--- a/javatests/com/google/gitiles/doc/SimpleMermaidRendererSecurityTest.java
+++ b/javatests/com/google/gitiles/doc/SimpleMermaidRendererSecurityTest.java
@@ -16,9 +16,11 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import com.google.common.html.types.SafeHtml;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Optional;
+import org.commonmark.node.Node;
 import org.eclipse.jgit.lib.Config;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -66,15 +68,19 @@
   public void testForeignObjectAndEmbeddedHtmlInLabels() {
     List<String> payloads =
         Arrays.asList(
-            "<foreignObject><body xmlns=\"http://www.w3.org/1999/xhtml\"><script>alert(1)</script></body></foreignObject>",
+            "<foreignObject><body"
+                + " xmlns=\"http://www.w3.org/1999/xhtml\"><script>alert(1)</script></body></foreignObject>",
             "<foreignObject><iframe src=\"javascript:alert(1)\"></iframe></foreignObject>",
             "<foreignObject><iframe src=\"https://evil.com\"></iframe></foreignObject>",
-            "<foreignObject><form action=\"//evil.com\"><input type=\"password\" name=\"pass\"></form></foreignObject>",
+            "<foreignObject><form action=\"//evil.com\"><input type=\"password\""
+                + " name=\"pass\"></form></foreignObject>",
             "<foreignObject><embed src=\"evil.swf\"></embed></foreignObject>",
             "<foreignObject><object data=\"javascript:alert(1)\"></object></foreignObject>",
             "<foreignObject><audio src=\"x\" onerror=\"alert(1)\"></audio></foreignObject>",
             "<foreignObject><video src=\"x\" onerror=\"alert(1)\"></video></foreignObject>",
-            "<foreignObject width=\"100\" height=\"100\"><div xmlns=\"http://www.w3.org/1999/xhtml\"><span>HTML Content</span></div></foreignObject>");
+            "<foreignObject width=\"100\" height=\"100\"><div"
+                + " xmlns=\"http://www.w3.org/1999/xhtml\"><span>HTML"
+                + " Content</span></div></foreignObject>");
 
     for (String payload : payloads) {
       String code = "graph TD\n  A[\"" + payload.replace("\"", "\\\"") + "\"] --> B\n";
@@ -149,7 +155,8 @@
             "<animate attributeName=\"xlink:href\" values=\"javascript:alert(1)\" dur=\"1s\" />",
             "<set onbegin=\"alert('set-begin')\" attributeName=\"x\" dur=\"1s\" />",
             "<set attributeName=\"onmouseover\" to=\"alert(1)\" />",
-            "<animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0\" to=\"360\" onend=\"alert(1)\" />");
+            "<animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0\" to=\"360\""
+                + " onend=\"alert(1)\" />");
 
     for (String payload : payloads) {
       String code = "graph TD\n  A[\"" + payload.replace("\"", "\\\"") + "\"] --> B\n";
@@ -167,7 +174,8 @@
         Arrays.asList(
             "<use href=\"javascript:alert(1)\" />",
             "<use xlink:href=\"javascript:alert(1)\" />",
-            "<use href=\"data:image/svg+xml;utf8,<svg id='x' xmlns='http://www.w3.org/2000/svg'><script>alert(1)</script></svg>#x\" />",
+            "<use href=\"data:image/svg+xml;utf8,<svg id='x'"
+                + " xmlns='http://www.w3.org/2000/svg'><script>alert(1)</script></svg>#x\" />",
             "<use xlink:href=\"https://evil.com/payload.svg#icon\" />",
             "<image href=\"javascript:alert(1)\" />",
             "<image xlink:href=\"javascript:alert(1)\" />",
@@ -195,7 +203,8 @@
             "<style>body { background: url(\"javascript:alert(1)\"); }</style>",
             "<style>* { -moz-binding: url('http://evil.com/xss.xml#test'); }</style>",
             "<style>svg { behavior: url(xss.htc); }</style>",
-            "<style>@keyframes xss { from { background-image: url('javascript:alert(1)'); } } </style>",
+            "<style>@keyframes xss { from { background-image: url('javascript:alert(1)'); } }"
+                + " </style>",
             "<div style=\"fill:expression(alert(1))\">Styled Div</div>",
             "<div style=\"background-image:url(javascript:alert(1))\">Background</div>",
             "<div style=\"behavior:url(xss.htc)\">HTC Component</div>");
@@ -278,7 +287,9 @@
     for (String payload : payloads) {
       String code =
           "graph TD\n"
-              + "  subgraph Sg [\"" + payload.replace("\"", "\\\"") + "\"]\n"
+              + "  subgraph Sg [\""
+              + payload.replace("\"", "\\\"")
+              + "\"]\n"
               + "    A[Node A]\n"
               + "  end\n"
               + "  A --> B\n";
@@ -293,16 +304,18 @@
   @Test
   public void testMermaidDirectivesCannotInjectCode() {
     String code =
-        "graph TD\n"
-            + "  A[Node A] --> B[Node B]\n"
-            + "  click A href \"javascript:alert('click-href')\"\n"
-            + "  click B call alert('click-call')\n"
-            + "  click A \"javascript:alert('click-positional')\"\n"
-            + "  style A fill:url(javascript:alert('style-fill'))\n"
-            + "  style B stroke:url(data:image/svg+xml,<svg onload=alert(1)>)\n"
-            + "  classDef evil fill:red,stroke:url(javascript:alert(1));\n"
-            + "  class A evil\n"
-            + "  linkStyle 0 stroke:url(javascript:alert(1));\n";
+        """
+        graph TD
+          A[Node A] --> B[Node B]
+          click A href "javascript:alert('click-href')"
+          click B call alert('click-call')
+          click A "javascript:alert('click-positional')"
+          style A fill:url(javascript:alert('style-fill'))
+          style B stroke:url(data:image/svg+xml,<svg onload=alert(1)>)
+          classDef evil fill:red,stroke:url(javascript:alert(1));
+          class A evil
+          linkStyle 0 stroke:url(javascript:alert(1));
+        """;
 
     SvgDoc svg = SvgDoc.render(code);
     svg.assertNoDangerousTags();
@@ -363,23 +376,26 @@
   @Test
   public void testEndToEndMarkdownXssPrevention() {
     String md =
-        "# Security Audit Title\n\n"
-            + "```mermaid\n"
-            + "graph TD\n"
-            + "  A[\"<script>alert('e2e-node')</script>\"]\n"
-            + "  B[\"<iframe src='javascript:alert(1)'></iframe>\"]\n"
-            + "  C[\"<img src=x onerror=alert('e2e-img')>\"]\n"
-            + "  D[\"<foreignObject><iframe src='http://evil.com'></iframe></foreignObject>\"]\n"
-            + "  A -->|\"<script>alert('e2e-edge')</script>\"| B\n"
-            + "  B --> C --> D\n"
-            + "  click A href \"javascript:alert('e2e-click')\"\n"
-            + "```\n";
+        """
+        # Security Audit Title
+
+        ```mermaid
+        graph TD
+          A["<script>alert('e2e-node')</script>"]
+          B["<iframe src='javascript:alert(1)'></iframe>"]
+          C["<img src=x onerror=alert('e2e-img')>"]
+          D["<foreignObject><iframe src='http://evil.com'></iframe></foreignObject>"]
+          A -->|"<script>alert('e2e-edge')</script>"| B
+          B --> C --> D
+          click A href "javascript:alert('e2e-click')"
+        ```
+        """;
 
     Config cfg = new Config();
     cfg.setBoolean("markdown", null, "mermaid", true);
     MarkdownConfig mc = new MarkdownConfig(cfg);
-    org.commonmark.node.Node node = GitilesMarkdown.parse(mc, md);
-    com.google.common.html.types.SafeHtml html =
+    Node node = GitilesMarkdown.parse(mc, md);
+    SafeHtml html =
         MarkdownToHtml.builder()
             .setConfig(mc)
             .setFilePath("security_test.md")
@@ -401,7 +417,8 @@
 
     // Verify all payloads are safely encoded as XML entity text
     assertThat(htmlStr).contains("&lt;script&gt;alert(&apos;e2e-node&apos;)&lt;/script&gt;");
-    assertThat(htmlStr).contains("&lt;iframe src=&apos;javascript:alert(1)&apos;&gt;&lt;/iframe&gt;");
+    assertThat(htmlStr)
+        .contains("&lt;iframe src=&apos;javascript:alert(1)&apos;&gt;&lt;/iframe&gt;");
     assertThat(htmlStr).contains("&lt;img src=x onerror=alert(&apos;e2e-img&apos;)&gt;");
   }
 
@@ -411,7 +428,7 @@
 
   private void assertSafeSvg(String mermaidCode, String originalPayload) {
     Optional<String> svgOpt = SimpleMermaidRenderer.renderToSvg(mermaidCode);
-    assertThat(svgOpt.isPresent()).isTrue();
+    assertThat(svgOpt).isPresent();
 
     String rawSvg = svgOpt.get();
 
diff --git a/javatests/com/google/gitiles/doc/SimpleMermaidRendererTest.java b/javatests/com/google/gitiles/doc/SimpleMermaidRendererTest.java
index 093b8f0..2d32676 100644
--- a/javatests/com/google/gitiles/doc/SimpleMermaidRendererTest.java
+++ b/javatests/com/google/gitiles/doc/SimpleMermaidRendererTest.java
@@ -29,9 +29,11 @@
 public class SimpleMermaidRendererTest {
 
   @Test
-  public void testConstructorInstantiation() {
-    SimpleMermaidRenderer renderer = new SimpleMermaidRenderer();
-    assertThat(renderer).isNotNull();
+  public void testConstructorInstantiation() throws Exception {
+    java.lang.reflect.Constructor<SimpleMermaidRenderer> c =
+        SimpleMermaidRenderer.class.getDeclaredConstructor();
+    c.setAccessible(true);
+    assertThat(c.newInstance()).isNotNull();
   }
 
   @Test
@@ -40,8 +42,8 @@
     svg.assertDefs();
 
     // Verify exactly 2 node rects and 1 edge path
-    assertThat(svg.getElementsByTag("rect").size()).isEqualTo(2);
-    assertThat(svg.getElementsByTag("path").size()).isEqualTo(2); // 1 arrow in defs + 1 edge
+    assertThat(svg.getElementsByTag("rect")).hasSize(2);
+    assertThat(svg.getElementsByTag("path")).hasSize(2); // 1 arrow in defs + 1 edge
 
     // Verify exact node texts
     List<String> texts = svg.getAllTextContents();
@@ -74,22 +76,33 @@
   @Test
   public void testAllNodeShapesExactSvgElements() {
     String code =
-        "graph TD\n"
-            + "  A[Rectangle Box]\n"
-            + "  B(Rounded Ball)\n"
-            + "  C([Stadium Ring])\n"
-            + "  D[[Subroutine Cart]]\n"
-            + "  E[(Cylinder Drum)]\n"
-            + "  F((Circle Star))\n"
-            + "  G{{Hexagon Block}}\n"
-            + "  H{Diamond Kite}\n"
-            + "  I>Asymmetric Flag]\n";
+        """
+        graph TD
+          A[Rectangle Box]
+          B(Rounded Ball)
+          C([Stadium Ring])
+          D[[Subroutine Cart]]
+          E[(Cylinder Drum)]
+          F((Circle Star))
+          G{{Hexagon Block}}
+          H{Diamond Kite}
+          I>Asymmetric Flag]
+        """;
     SvgDoc svg = render(code);
 
     // Exact text elements
     List<String> texts = svg.getAllTextContents();
-    assertThat(texts).containsExactly(
-        "Rectangle Box", "Rounded Ball", "Stadium Ring", "Subroutine Cart", "Cylinder Drum", "Circle Star", "Hexagon Block", "Diamond Kite", "Asymmetric Flag")
+    assertThat(texts)
+        .containsExactly(
+            "Rectangle Box",
+            "Rounded Ball",
+            "Stadium Ring",
+            "Subroutine Cart",
+            "Cylinder Drum",
+            "Circle Star",
+            "Hexagon Block",
+            "Diamond Kite",
+            "Asymmetric Flag")
         .inOrder();
 
     // Verify Diamond has a polygon with 4 vertices
@@ -108,24 +121,26 @@
 
     // Verify Subroutine has rect with 2 inner border lines
     List<Element> lines = svg.getElementsByTag("line");
-    assertThat(lines.size()).isEqualTo(2);
+    assertThat(lines).hasSize(2);
 
     // Verify Cylinder has 2 paths (body + top rim arc)
     List<Element> paths = svg.getEdgePaths();
-    assertThat(paths.size()).isEqualTo(2);
+    assertThat(paths).hasSize(2);
   }
 
   @Test
   public void testMultilineNodeLabelsWithTspans() {
     String code =
-        "graph TD\n"
-            + "  A[\"Sunny Blue Sky<br/>Warm Golden Sun<br/>Soft Green Grass\"]\n"
-            + "  B[\"Little Red Apple\"]\n"
-            + "  A --> B\n";
+        """
+        graph TD
+          A["Sunny Blue Sky<br/>Warm Golden Sun<br/>Soft Green Grass"]
+          B["Little Red Apple"]
+          A --> B
+        """;
     SvgDoc svg = render(code);
 
     List<Element> tspans = svg.getElementsByTag("tspan");
-    assertThat(tspans.size()).isEqualTo(3);
+    assertThat(tspans).hasSize(3);
     assertThat(tspans.get(0).getTextContent()).isEqualTo("Sunny Blue Sky");
     assertThat(tspans.get(0).getAttribute("font-weight")).isEqualTo("600");
     assertThat(tspans.get(0).getAttribute("dy")).isEqualTo("0");
@@ -146,18 +161,19 @@
   @Test
   public void testQuotedLabelsWithBracketsAndEntities() {
     String code =
-        "graph TD\n"
-            + "  A[\"Play with teddy bear\"]\n"
-            + "  B[\"Find [Puppy] in cozy room\"]\n"
-            + "  C{\"Is kitten <tiny> & 'sweet'?\"}\n"
-            + "  A --> B --> C\n";
+        """
+        graph TD
+          A["Play with teddy bear"]
+          B["Find [Puppy] in cozy room"]
+          C{"Is kitten <tiny> & 'sweet'?"}
+          A --> B --> C
+        """;
     SvgDoc svg = render(code);
 
     // XML parsing confirms correct unescaping of &lt;, &gt;, &apos;, &amp;
-    assertThat(svg.getAllTextContents()).containsExactly(
-        "Play with teddy bear",
-        "Find [Puppy] in cozy room",
-        "Is kitten <tiny> & 'sweet'?")
+    assertThat(svg.getAllTextContents())
+        .containsExactly(
+            "Play with teddy bear", "Find [Puppy] in cozy room", "Is kitten <tiny> & 'sweet'?")
         .inOrder();
   }
 
@@ -170,24 +186,26 @@
   @Test
   public void testAllEdgeTypesAndInfixLabelsExactAttributes() {
     String code =
-        "graph LR\n"
-            + "  A -->|Yellow Duck| B\n"
-            + "  B ---|Blue Bird| C\n"
-            + "  C -.->|Green Frog| D\n"
-            + "  D ==>|Red Puppy| E\n"
-            + "  E -- Orange Kitten --> F\n"
-            + "  F -- Purple Bunny --- G\n"
-            + "  G == White Lamb ==> H\n"
-            + "  H == Pink Piggy === I\n"
-            + "  I -. Brown Bear .-> J\n"
-            + "  J -. Gray Mouse .- K\n"
-            + "  K -.- L\n"
-            + "  L === M\n"
-            + "  M <--> N\n";
+        """
+        graph LR
+          A -->|Yellow Duck| B
+          B ---|Blue Bird| C
+          C -.->|Green Frog| D
+          D ==>|Red Puppy| E
+          E -- Orange Kitten --> F
+          F -- Purple Bunny --- G
+          G == White Lamb ==> H
+          H == Pink Piggy === I
+          I -. Brown Bear .-> J
+          J -. Gray Mouse .- K
+          K -.- L
+          L === M
+          M <--> N
+        """;
     SvgDoc svg = render(code);
 
     List<Element> edgePaths = svg.getEdgePaths();
-    assertThat(edgePaths.size()).isEqualTo(13);
+    assertThat(edgePaths).hasSize(13);
 
     // Verify dashed stroke
     Element dashedEdge = edgePaths.get(2);
@@ -220,33 +238,35 @@
   @Test
   public void testSubgraphsWithTitlesAliasesAndDirectionOverrides() {
     String code =
-        "graph TD\n"
-            + "  subgraph Playground Park\n"
-            + "    direction LR\n"
-            + "    E1(puppy)\n"
-            + "    E2(kitten)\n"
-            + "  end\n"
-            + "  subgraph ToyHouse [\"Magic Toy House\"]\n"
-            + "    direction INVALID_DIR\n"
-            + "    S1[(Teddy)]\n"
-            + "  end\n"
-            + "  subgraph \"Music Tree Castle\"\n"
-            + "    T1[Wooden Blocks]\n"
-            + "  end\n"
-            + "  subgraph MeadowHill [Sunny Meadow Hill]\n"
-            + "    U1[Little Duck]\n"
-            + "  end\n"
-            + "  Baby --> E1\n"
-            + "  E1 --> ToyHouse\n"
-            + "  ToyHouse --> T1\n"
-            + "  T1 --> MeadowHill\n";
+        """
+        graph TD
+          subgraph Playground Park
+            direction LR
+            E1(puppy)
+            E2(kitten)
+          end
+          subgraph ToyHouse ["Magic Toy House"]
+            direction INVALID_DIR
+            S1[(Teddy)]
+          end
+          subgraph "Music Tree Castle"
+            T1[Wooden Blocks]
+          end
+          subgraph MeadowHill [Sunny Meadow Hill]
+            U1[Little Duck]
+          end
+          Baby --> E1
+          E1 --> ToyHouse
+          ToyHouse --> T1
+          T1 --> MeadowHill
+        """;
     SvgDoc svg = render(code);
     svg.assertNoLabelNodeOverlaps();
     svg.assertSubgraphsDoNotOverlap();
 
     // Verify 4 subgraph boundary rects (stroke-dasharray="4,4")
     List<Element> subgraphs = svg.findSubgraphRects();
-    assertThat(subgraphs.size()).isEqualTo(4);
+    assertThat(subgraphs).hasSize(4);
     for (Element sgRect : subgraphs) {
       assertThat(sgRect.getAttribute("stroke-dasharray")).isEqualTo("4,4");
       assertThat(sgRect.getAttribute("rx")).isEqualTo("8");
@@ -261,70 +281,78 @@
 
   @Test
   public void testSubgraphToSubgraphAndSubgraphToNodeEdges() {
-    String codeTD =
-        "graph TD\n"
-            + "  subgraph SubA [\"Garden A\"]\n"
-            + "    A1[Daisy Flower]\n"
-            + "  end\n"
-            + "  subgraph SubB [\"Garden B\"]\n"
-            + "    B1[Tulip Flower]\n"
-            + "  end\n"
-            + "  SubA -->|Garden Link TD| SubB\n"
-            + "  SubA -->|Flower Link| NodeC[Red Rose]\n"
-            + "  NodeC -->|Petal Link| SubB\n";
-    SvgDoc svgTD = render(codeTD);
-    assertThat(svgTD.findText("Garden Link TD")).isNotNull();
-    assertThat(svgTD.findText("Flower Link")).isNotNull();
-    assertThat(svgTD.findText("Petal Link")).isNotNull();
-    assertThat(svgTD.getElementsByTag("path")).isNotEmpty();
+    String codeTd =
+        """
+        graph TD
+          subgraph SubA ["Garden A"]
+            A1[Daisy Flower]
+          end
+          subgraph SubB ["Garden B"]
+            B1[Tulip Flower]
+          end
+          SubA -->|Garden Link TD| SubB
+          SubA -->|Flower Link| NodeC[Red Rose]
+          NodeC -->|Petal Link| SubB
+        """;
+    SvgDoc svgTd = render(codeTd);
+    assertThat(svgTd.findText("Garden Link TD")).isNotNull();
+    assertThat(svgTd.findText("Flower Link")).isNotNull();
+    assertThat(svgTd.findText("Petal Link")).isNotNull();
+    assertThat(svgTd.getElementsByTag("path")).isNotEmpty();
 
-    String codeLR =
-        "graph LR\n"
-            + "  subgraph SubA [\"Garden A\"]\n"
-            + "    A1[Daisy Flower]\n"
-            + "  end\n"
-            + "  subgraph SubB [\"Garden B\"]\n"
-            + "    B1[Tulip Flower]\n"
-            + "  end\n"
-            + "  SubA -->|Garden Link LR| SubB\n";
-    SvgDoc svgLR = render(codeLR);
-    assertThat(svgLR.findText("Garden Link LR")).isNotNull();
+    String codeLr =
+        """
+        graph LR
+          subgraph SubA ["Garden A"]
+            A1[Daisy Flower]
+          end
+          subgraph SubB ["Garden B"]
+            B1[Tulip Flower]
+          end
+          SubA -->|Garden Link LR| SubB
+        """;
+    SvgDoc svgLr = render(codeLr);
+    assertThat(svgLr.findText("Garden Link LR")).isNotNull();
 
-    String codeLRWithBlockedNode =
-        "graph LR\n"
-            + "  subgraph SubA [\"Garden A\"]\n"
-            + "    A1[Daisy Flower]\n"
-            + "  end\n"
-            + "  subgraph SubB [\"Garden B\"]\n"
-            + "    B1[Tulip Flower]\n"
-            + "  end\n"
-            + "  SubA -->|Garden Link LR Blocked| SubB\n"
-            + "  SubA -->|Flower Link LR| NodeC[Red Rose]\n"
-            + "  NodeC -->|Petal Link LR| SubB\n";
-    SvgDoc svgLRBlocked = render(codeLRWithBlockedNode);
-    assertThat(svgLRBlocked.findText("Garden Link LR Blocked")).isNotNull();
-    assertThat(svgLRBlocked.findText("Flower Link LR")).isNotNull();
-    assertThat(svgLRBlocked.findText("Petal Link LR")).isNotNull();
+    String codeLrWithBlockedNode =
+        """
+        graph LR
+          subgraph SubA ["Garden A"]
+            A1[Daisy Flower]
+          end
+          subgraph SubB ["Garden B"]
+            B1[Tulip Flower]
+          end
+          SubA -->|Garden Link LR Blocked| SubB
+          SubA -->|Flower Link LR| NodeC[Red Rose]
+          NodeC -->|Petal Link LR| SubB
+        """;
+    SvgDoc svgLrBlocked = render(codeLrWithBlockedNode);
+    assertThat(svgLrBlocked.findText("Garden Link LR Blocked")).isNotNull();
+    assertThat(svgLrBlocked.findText("Flower Link LR")).isNotNull();
+    assertThat(svgLrBlocked.findText("Petal Link LR")).isNotNull();
   }
 
   @Test
   public void testNestedSubgraphsExactHierarchy() {
     String code =
-        "graph TD\n"
-            + "  subgraph Sandbox [\"Play Sandbox\"]\n"
-            + "    subgraph SandCastle [\"Sand Castle\"]\n"
-            + "      SPA[\"Red Bucket\"]\n"
-            + "    end\n"
-            + "    subgraph ToyPond [\"Toy Pond\"]\n"
-            + "      CS[\"Yellow Boat\"]\n"
-            + "    end\n"
-            + "  end\n"
-            + "  SPA -->|Water Splash| CS\n";
+        """
+        graph TD
+          subgraph Sandbox ["Play Sandbox"]
+            subgraph SandCastle ["Sand Castle"]
+              SPA["Red Bucket"]
+            end
+            subgraph ToyPond ["Toy Pond"]
+              CS["Yellow Boat"]
+            end
+          end
+          SPA -->|Water Splash| CS
+        """;
     SvgDoc svg = render(code);
 
     // Exactly 3 subgraph boxes (1 outer + 2 inner)
     List<Element> subgraphs = svg.findSubgraphRects();
-    assertThat(subgraphs.size()).isEqualTo(3);
+    assertThat(subgraphs).hasSize(3);
 
     assertThat(svg.findText("Play Sandbox")).isNotNull();
     assertThat(svg.findText("Sand Castle")).isNotNull();
@@ -337,82 +365,94 @@
   @Test
   public void testNestedSubgraphsHorizontal() {
     String code =
-        "graph LR\n"
-            + "  subgraph Outer [\"Playhouse\"]\n"
-            + "    subgraph InnerA [\"Kitten Corner\"]\n"
-            + "      A1[Soft Pillow]\n"
-            + "    end\n"
-            + "    subgraph InnerB [\"Puppy Corner\"]\n"
-            + "      B1[Squeaky Ball]\n"
-            + "    end\n"
-            + "  end\n"
-            + "  A1 -->|Play Time| B1\n";
+        """
+        graph LR
+          subgraph Outer ["Playhouse"]
+            subgraph InnerA ["Kitten Corner"]
+              A1[Soft Pillow]
+            end
+            subgraph InnerB ["Puppy Corner"]
+              B1[Squeaky Ball]
+            end
+          end
+          A1 -->|Play Time| B1
+        """;
     SvgDoc svg = render(code);
     assertThat(svg.findText("Play Time")).isNotNull();
   }
 
   @Test
   public void testSubgraphWithMixedChildrenAndDirectNodes() {
-    String codeTD =
-        "graph TD\n"
-            + "  subgraph OuterTD [\"Tree House TD\"]\n"
-            + "    subgraph InnerTD [\"Bird Nest TD\"]\n"
-            + "      A1[Baby Bird TD]\n"
-            + "    end\n"
-            + "    D1[Little Squirrel TD]\n"
-            + "  end\n"
-            + "  A1 --> D1\n";
-    SvgDoc svgTD = render(codeTD);
-    assertThat(svgTD.findText("Tree House TD")).isNotNull();
-    assertThat(svgTD.findText("Bird Nest TD")).isNotNull();
-    assertThat(svgTD.findText("Little Squirrel TD")).isNotNull();
+    String codeTd =
+        """
+        graph TD
+          subgraph OuterTD ["Tree House TD"]
+            subgraph InnerTD ["Bird Nest TD"]
+              A1[Baby Bird TD]
+            end
+            D1[Little Squirrel TD]
+          end
+          A1 --> D1
+        """;
+    SvgDoc svgTd = render(codeTd);
+    assertThat(svgTd.findText("Tree House TD")).isNotNull();
+    assertThat(svgTd.findText("Bird Nest TD")).isNotNull();
+    assertThat(svgTd.findText("Little Squirrel TD")).isNotNull();
 
-    String codeLR =
-        "graph LR\n"
-            + "  subgraph OuterLR [\"Tree House LR\"]\n"
-            + "    subgraph InnerLR [\"Bird Nest LR\"]\n"
-            + "      A1[Baby Bird LR]\n"
-            + "    end\n"
-            + "    D1[Little Squirrel LR]\n"
-            + "  end\n"
-            + "  A1 --> D1\n";
-    SvgDoc svgLR = render(codeLR);
-    assertThat(svgLR.findText("Tree House LR")).isNotNull();
-    assertThat(svgLR.findText("Bird Nest LR")).isNotNull();
-    assertThat(svgLR.findText("Little Squirrel LR")).isNotNull();
+    String codeLr =
+        """
+        graph LR
+          subgraph OuterLR ["Tree House LR"]
+            subgraph InnerLR ["Bird Nest LR"]
+              A1[Baby Bird LR]
+            end
+            D1[Little Squirrel LR]
+          end
+          A1 --> D1
+        """;
+    SvgDoc svgLr = render(codeLr);
+    assertThat(svgLr.findText("Tree House LR")).isNotNull();
+    assertThat(svgLr.findText("Bird Nest LR")).isNotNull();
+    assertThat(svgLr.findText("Little Squirrel LR")).isNotNull();
   }
 
   @Test
   public void testNestedSubgraphWithLabeledAdjacentEdge() {
-    String codeTD =
-        "graph TD\n"
-            + "  subgraph SubTD [\"Animal Farm TD\"]\n"
-            + "    A[Happy Lamb]\n"
-            + "    B[Little Pony]\n"
-            + "    A -->|Green Grass TD| B\n"
-            + "  end\n";
-    SvgDoc svgTD = render(codeTD);
-    assertThat(svgTD.findText("Green Grass TD")).isNotNull();
+    String codeTd =
+        """
+        graph TD
+          subgraph SubTD ["Animal Farm TD"]
+            A[Happy Lamb]
+            B[Little Pony]
+            A -->|Green Grass TD| B
+          end
+        """;
+    SvgDoc svgTd = render(codeTd);
+    assertThat(svgTd.findText("Green Grass TD")).isNotNull();
 
-    String codeLR =
-        "graph LR\n"
-            + "  subgraph SubLR [\"Animal Farm LR\"]\n"
-            + "    A[Happy Lamb]\n"
-            + "    B[Little Pony]\n"
-            + "    A -->|Green Grass LR| B\n"
-            + "  end\n";
-    SvgDoc svgLR = render(codeLR);
-    assertThat(svgLR.findText("Green Grass LR")).isNotNull();
+    String codeLr =
+        """
+        graph LR
+          subgraph SubLR ["Animal Farm LR"]
+            A[Happy Lamb]
+            B[Little Pony]
+            A -->|Green Grass LR| B
+          end
+        """;
+    SvgDoc svgLr = render(codeLr);
+    assertThat(svgLr.findText("Green Grass LR")).isNotNull();
   }
 
   @Test
   public void testSugiyamaLateralAdjacentLabeledEdge() {
     String code =
-        "graph TD\n"
-            + "  A1[Fuzzy Panda] --> B1[Baby Giraffe]\n"
-            + "  A2[Little Koala] --> B2[Tiny Hamster]\n"
-            + "  A1 -->|Sunny Day| A2\n"
-            + "  B1 -->|Happy Play| B2\n";
+        """
+        graph TD
+          A1[Fuzzy Panda] --> B1[Baby Giraffe]
+          A2[Little Koala] --> B2[Tiny Hamster]
+          A1 -->|Sunny Day| A2
+          B1 -->|Happy Play| B2
+        """;
     SvgDoc svg = render(code);
     assertThat(svg.findText("Sunny Day")).isNotNull();
     assertThat(svg.findText("Happy Play")).isNotNull();
@@ -420,78 +460,92 @@
 
   @Test
   public void testBidirectionalMutualEdgesBothOrientations() {
-    String codeTD =
-        "graph TD\n"
-            + "  A[\"Little Lamb\"]\n"
-            + "  B[\"Sweet Bunny\"]\n"
-            + "  A -->|Hop Down| B\n"
-            + "  B -->|Jump Up| A\n";
-    SvgDoc svgTD = render(codeTD);
-    assertThat(svgTD.findText("Hop Down")).isNotNull();
-    assertThat(svgTD.findText("Jump Up")).isNotNull();
+    String codeTd =
+        """
+        graph TD
+          A["Little Lamb"]
+          B["Sweet Bunny"]
+          A -->|Hop Down| B
+          B -->|Jump Up| A
+        """;
+    SvgDoc svgTd = render(codeTd);
+    assertThat(svgTd.findText("Hop Down")).isNotNull();
+    assertThat(svgTd.findText("Jump Up")).isNotNull();
     // Exactly 2 mutual curved edge paths
-    assertThat(svgTD.getEdgePaths().size()).isEqualTo(2);
+    assertThat(svgTd.getEdgePaths()).hasSize(2);
 
-    String codeLR =
-        "graph LR\n"
-            + "  A[\"Little Lamb\"]\n"
-            + "  B[\"Sweet Bunny\"]\n"
-            + "  A -->|Run Forward| B\n"
-            + "  B -->|Run Backward| A\n";
-    SvgDoc svgLR = render(codeLR);
-    assertThat(svgLR.findText("Run Forward")).isNotNull();
-    assertThat(svgLR.findText("Run Backward")).isNotNull();
-    assertThat(svgLR.getEdgePaths().size()).isEqualTo(2);
+    String codeLr =
+        """
+        graph LR
+          A["Little Lamb"]
+          B["Sweet Bunny"]
+          A -->|Run Forward| B
+          B -->|Run Backward| A
+        """;
+    SvgDoc svgLr = render(codeLr);
+    assertThat(svgLr.findText("Run Forward")).isNotNull();
+    assertThat(svgLr.findText("Run Backward")).isNotNull();
+    assertThat(svgLr.getEdgePaths()).hasSize(2);
   }
 
   @Test
   public void testCycleDetectionAndLoopbackBothOrientations() {
-    String codeTD =
-        "graph TD\n"
-            + "  A --> B\n"
-            + "  B --> C\n"
-            + "  C -->|Loop TD| A\n";
-    SvgDoc svgTD = render(codeTD);
-    assertThat(svgTD.findText("Loop TD")).isNotNull();
-    assertThat(svgTD.getEdgePaths().size()).isEqualTo(3);
+    String codeTd =
+        """
+        graph TD
+          A --> B
+          B --> C
+          C -->|Loop TD| A
+        """;
+    SvgDoc svgTd = render(codeTd);
+    assertThat(svgTd.findText("Loop TD")).isNotNull();
+    assertThat(svgTd.getEdgePaths()).hasSize(3);
 
-    String codeLR =
-        "graph LR\n"
-            + "  A --> B\n"
-            + "  B --> C\n"
-            + "  C -->|Loop LR| A\n";
-    SvgDoc svgLR = render(codeLR);
-    assertThat(svgLR.findText("Loop LR")).isNotNull();
-    assertThat(svgLR.getEdgePaths().size()).isEqualTo(3);
+    String codeLr =
+        """
+        graph LR
+          A --> B
+          B --> C
+          C -->|Loop LR| A
+        """;
+    SvgDoc svgLr = render(codeLr);
+    assertThat(svgLr.findText("Loop LR")).isNotNull();
+    assertThat(svgLr.getEdgePaths()).hasSize(3);
   }
 
   @Test
   public void testSkipLayerBypassBothOrientations() {
-    String codeTD =
-        "graph TD\n"
-            + "  A --> B\n"
-            + "  B --> C\n"
-            + "  A -->|Skip TD| C\n";
-    SvgDoc svgTD = render(codeTD);
-    assertThat(svgTD.findText("Skip TD")).isNotNull();
+    String codeTd =
+        """
+        graph TD
+          A --> B
+          B --> C
+          A -->|Skip TD| C
+        """;
+    SvgDoc svgTd = render(codeTd);
+    assertThat(svgTd.findText("Skip TD")).isNotNull();
 
-    String codeLR =
-        "graph LR\n"
-            + "  A --> B\n"
-            + "  B --> C\n"
-            + "  A -->|Skip LR| C\n";
-    SvgDoc svgLR = render(codeLR);
-    assertThat(svgLR.findText("Skip LR")).isNotNull();
+    String codeLr =
+        """
+        graph LR
+          A --> B
+          B --> C
+          A -->|Skip LR| C
+        """;
+    SvgDoc svgLr = render(codeLr);
+    assertThat(svgLr.findText("Skip LR")).isNotNull();
   }
 
   @Test
   public void testHorizontalGraphWithCycleAndLongSpanEdge() {
     String code =
-        "graph LR\n"
-            + "  A[Happy Kitten] --> B[Playful Puppy]\n"
-            + "  B --> C[Cozy Hamster]\n"
-            + "  C -->|Run Back| A\n"
-            + "  A -->|Long Leap| C\n";
+        """
+        graph LR
+          A[Happy Kitten] --> B[Playful Puppy]
+          B --> C[Cozy Hamster]
+          C -->|Run Back| A
+          A -->|Long Leap| C
+        """;
     SvgDoc doc = render(code);
     assertThat(doc.findText("Happy Kitten")).isNotNull();
     assertThat(doc.findText("Playful Puppy")).isNotNull();
@@ -503,12 +557,14 @@
   @Test
   public void testNestedSubgraphWithLooseSourceCompaction() {
     String code =
-        "graph TD\n"
-            + "  subgraph Meadow [\"Sunny Green Meadow\"]\n"
-            + "    A[Bright Buttercup] --> B[Busy Ant]\n"
-            + "    B --> C[Tall Oak Tree]\n"
-            + "    D[Quiet Snail] --> C\n"
-            + "  end\n";
+        """
+        graph TD
+          subgraph Meadow ["Sunny Green Meadow"]
+            A[Bright Buttercup] --> B[Busy Ant]
+            B --> C[Tall Oak Tree]
+            D[Quiet Snail] --> C
+          end
+        """;
     SvgDoc doc = render(code);
     assertThat(doc.findText("Sunny Green Meadow")).isNotNull();
     assertThat(doc.findText("Bright Buttercup")).isNotNull();
@@ -520,16 +576,18 @@
   @Test
   public void testDirectivesAndStylingIgnoredGracefully() {
     String code =
-        "graph TD\n"
-            + "  accTitle: Cheerful Morning Playground\n"
-            + "  accDescr: Story of fluffy puppy and kitten\n"
-            + "  classDef default fill:#f9f,stroke:#333;\n"
-            + "  classDef special fill:#bbf,stroke:#333;\n"
-            + "  class A special\n"
-            + "  style B fill:#dfd,stroke:#333;\n"
-            + "  click A href \"https://example.com\"\n"
-            + "  linkStyle 0 stroke:#ff3,stroke-width:4px;\n"
-            + "  A[Little Kitten] --> B[Fluffy Bunny]\n";
+        """
+        graph TD
+          accTitle: Cheerful Morning Playground
+          accDescr: Story of fluffy puppy and kitten
+          classDef default fill:#f9f,stroke:#333;
+          classDef special fill:#bbf,stroke:#333;
+          class A special
+          style B fill:#dfd,stroke:#333;
+          click A href "https://example.com"
+          linkStyle 0 stroke:#ff3,stroke-width:4px;
+          A[Little Kitten] --> B[Fluffy Bunny]
+        """;
     SvgDoc svg = render(code);
     assertThat(svg.getAllTextContents()).containsExactly("Little Kitten", "Fluffy Bunny").inOrder();
   }
@@ -537,9 +595,11 @@
   @Test
   public void testDisconnectedNodes() {
     SvgDoc svg = render("graph TD\n  A[Quiet Mouse]\n  B[Sleeping Turtle]\n  C --> D\n");
-    assertThat(svg.getAllTextContents()).containsExactly("Quiet Mouse", "Sleeping Turtle", "C", "D").inOrder();
-    assertThat(svg.getElementsByTag("rect").size()).isEqualTo(4);
-    assertThat(svg.getEdgePaths().size()).isEqualTo(1);
+    assertThat(svg.getAllTextContents())
+        .containsExactly("Quiet Mouse", "Sleeping Turtle", "C", "D")
+        .inOrder();
+    assertThat(svg.getElementsByTag("rect")).hasSize(4);
+    assertThat(svg.getEdgePaths()).hasSize(1);
   }
 
   @Test
@@ -550,11 +610,11 @@
 
   @Test
   public void testWhitespaceAndEmptyBlocks() {
-    assertThat(SimpleMermaidRenderer.renderToSvg("   \n\n\t").isPresent()).isFalse();
-    assertThat(SimpleMermaidRenderer.renderToSvg("graph TD\n").isPresent()).isFalse();
-    assertThat(SimpleMermaidRenderer.renderToSvg("graph TD\n%% only comments\n").isPresent()).isFalse();
-    assertThat(SimpleMermaidRenderer.renderToSvg("").isPresent()).isFalse();
-    assertThat(SimpleMermaidRenderer.renderToSvg(null).isPresent()).isFalse();
+    assertThat(SimpleMermaidRenderer.renderToSvg("   \n\n\t")).isEmpty();
+    assertThat(SimpleMermaidRenderer.renderToSvg("graph TD\n")).isEmpty();
+    assertThat(SimpleMermaidRenderer.renderToSvg("graph TD\n%% only comments\n")).isEmpty();
+    assertThat(SimpleMermaidRenderer.renderToSvg("")).isEmpty();
+    assertThat(SimpleMermaidRenderer.renderToSvg(null)).isEmpty();
   }
 
   @Test
@@ -563,8 +623,7 @@
     SvgDoc svg = render(code);
     assertThat(svg.getAllTextContents()).containsExactly("A", "B").inOrder();
 
-    assertThat(SimpleMermaidRenderer.renderToSvg("%% only comments\nsome random text\n").isPresent())
-        .isFalse();
+    assertThat(SimpleMermaidRenderer.renderToSvg("%% only comments\nsome random text\n")).isEmpty();
   }
 
   @Test
@@ -576,29 +635,35 @@
 
   @Test
   public void testAllUnsupportedDiagramTypesReturnEmpty() {
-    assertThat(SimpleMermaidRenderer.renderToSvg("sequenceDiagram\nAlice->>Bob: Hello\n").isPresent()).isFalse();
-    assertThat(SimpleMermaidRenderer.renderToSvg("classDiagram\nClass01 <|-- Class02\n").isPresent()).isFalse();
-    assertThat(SimpleMermaidRenderer.renderToSvg("erDiagram\nCUSTOMER ||--o{ ORDER : places\n").isPresent()).isFalse();
-    assertThat(SimpleMermaidRenderer.renderToSvg("gantt\ntitle A Gantt Diagram\n").isPresent()).isFalse();
-    assertThat(SimpleMermaidRenderer.renderToSvg("pie title Pets\n\"Dogs\" : 386\n").isPresent()).isFalse();
-    assertThat(SimpleMermaidRenderer.renderToSvg("gitGraph\ncommit\n").isPresent()).isFalse();
-    assertThat(SimpleMermaidRenderer.renderToSvg("xychart-beta\ntitle \"Score\"\n").isPresent()).isFalse();
-    assertThat(SimpleMermaidRenderer.renderToSvg("stateDiagram\n[*] --> Still\n").isPresent()).isFalse();
-    assertThat(SimpleMermaidRenderer.renderToSvg("stateDiagram-v2\n[*] --> Still\n").isPresent()).isFalse();
+    assertThat(SimpleMermaidRenderer.renderToSvg("sequenceDiagram\nAlice->>Bob: Hello\n"))
+        .isEmpty();
+    assertThat(SimpleMermaidRenderer.renderToSvg("classDiagram\nClass01 <|-- Class02\n")).isEmpty();
+    assertThat(SimpleMermaidRenderer.renderToSvg("erDiagram\nCUSTOMER ||--o{ ORDER : places\n"))
+        .isEmpty();
+    assertThat(SimpleMermaidRenderer.renderToSvg("gantt\ntitle A Gantt Diagram\n")).isEmpty();
+    assertThat(SimpleMermaidRenderer.renderToSvg("pie title Pets\n\"Dogs\" : 386\n")).isEmpty();
+    assertThat(SimpleMermaidRenderer.renderToSvg("gitGraph\ncommit\n")).isEmpty();
+    assertThat(SimpleMermaidRenderer.renderToSvg("xychart-beta\ntitle \"Score\"\n")).isEmpty();
+    assertThat(SimpleMermaidRenderer.renderToSvg("stateDiagram\n[*] --> Still\n")).isEmpty();
+    assertThat(SimpleMermaidRenderer.renderToSvg("stateDiagram-v2\n[*] --> Still\n")).isEmpty();
   }
 
   @Test
   public void testNodeReassignmentToSubgraph() {
     String code =
-        "graph TD\n"
-            + "  A[Singing Robin]\n"
-            + "  subgraph Sub\n"
-            + "    A\n"
-            + "    B[Flying Bluebird]\n"
-            + "  end\n"
-            + "  A --> B\n";
+        """
+        graph TD
+          A[Singing Robin]
+          subgraph Sub
+            A
+            B[Flying Bluebird]
+          end
+          A --> B
+        """;
     SvgDoc svg = render(code);
-    assertThat(svg.getAllTextContents()).containsExactly("Sub", "Singing Robin", "Flying Bluebird").inOrder();
+    assertThat(svg.getAllTextContents())
+        .containsExactly("Sub", "Singing Robin", "Flying Bluebird")
+        .inOrder();
   }
 
   @Test
@@ -609,12 +674,24 @@
     assertThat(doc1.findText("Sweet Honey Pie")).isNotNull();
 
     // Reverse edge in vertical nested subgraph
-    String code2 = "graph TD\n  subgraph Sub\n    A[Baby Chick]\n    B[Mama Hen]\n    B -->|Chirp Vert| A\n  end\n";
+    String code2 =
+        "graph TD\n"
+            + "  subgraph Sub\n"
+            + "    A[Baby Chick]\n"
+            + "    B[Mama Hen]\n"
+            + "    B -->|Chirp Vert| A\n"
+            + "  end\n";
     SvgDoc doc2 = render(code2);
     assertThat(doc2.findText("Chirp Vert")).isNotNull();
 
     // Reverse edge in horizontal nested subgraph
-    String code3 = "graph LR\n  subgraph Sub\n    A[Baby Chick]\n    B[Mama Hen]\n    B -->|Chirp Horiz| A\n  end\n";
+    String code3 =
+        "graph LR\n"
+            + "  subgraph Sub\n"
+            + "    A[Baby Chick]\n"
+            + "    B[Mama Hen]\n"
+            + "    B -->|Chirp Horiz| A\n"
+            + "  end\n";
     SvgDoc doc3 = render(code3);
     assertThat(doc3.findText("Chirp Horiz")).isNotNull();
 
@@ -624,7 +701,7 @@
 
     // Trailing non-edge characters to hit scanEdgeToken default return null
     String code6 = "graph TD\n  A 12345\n";
-    assertThat(SimpleMermaidRenderer.renderToSvg(code6).isPresent()).isTrue();
+    assertThat(SimpleMermaidRenderer.renderToSvg(code6)).isPresent();
   }
 
   private static SvgDoc render(String code) {
@@ -640,7 +717,7 @@
 
     // Redundant header line in body
     String code2 = "graph TD\n  graph TD\n  A --> B\n";
-    assertThat(SimpleMermaidRenderer.renderToSvg(code2).isPresent()).isTrue();
+    assertThat(SimpleMermaidRenderer.renderToSvg(code2)).isPresent();
 
     // Direct AST Node empty label setter
     SimpleMermaidRenderer.Node n = new SimpleMermaidRenderer.Node("testNode");
@@ -648,24 +725,30 @@
     assertThat(n.labelLines).containsExactly("");
 
     // Double quotes in label and title to exercise escapeXml
-    String code3 = "graph TD\n  subgraph Sg [\"Magic Castle with \\\"Stars\\\"\"]\n    A[\"Has \\\"Glitter\\\" in pocket\"]\n  end\n";
-    assertThat(SimpleMermaidRenderer.renderToSvg(code3).isPresent()).isTrue();
+    String code3 =
+        "graph TD\n"
+            + "  subgraph Sg [\"Magic Castle with \\\"Stars\\\"\"]\n"
+            + "    A[\"Has \\\"Glitter\\\" in pocket\"]\n"
+            + "  end\n";
+    assertThat(SimpleMermaidRenderer.renderToSvg(code3)).isPresent();
   }
 
   @Test
   public void testSecurityNoScriptOrIframeExecutionInNodeLabels() {
     String code =
-        "graph TD\n"
-            + "  A[\"<script>alert('xss-script')</script>\"]\n"
-            + "  B[\"<iframe src='javascript:alert(1)'></iframe>\"]\n"
-            + "  C[\"<img src=x onerror=alert('img-onerror')>\"]\n"
-            + "  D[\"<svg onload=alert('svg-onload')>\"]\n"
-            + "  E[\"<foreignObject><iframe src='https://evil.com'></iframe></foreignObject>\"]\n"
-            + "  F[\"<a href='javascript:alert(1)'>Click Me</a>\"]\n"
-            + "  A --> B --> C --> D --> E --> F\n";
+        """
+        graph TD
+          A["<script>alert('xss-script')</script>"]
+          B["<iframe src='javascript:alert(1)'></iframe>"]
+          C["<img src=x onerror=alert('img-onerror')>"]
+          D["<svg onload=alert('svg-onload')>"]
+          E["<foreignObject><iframe src='https://evil.com'></iframe></foreignObject>"]
+          F["<a href='javascript:alert(1)'>Click Me</a>"]
+          A --> B --> C --> D --> E --> F
+        """;
 
     Optional<String> svgOpt = SimpleMermaidRenderer.renderToSvg(code);
-    assertThat(svgOpt.isPresent()).isTrue();
+    assertThat(svgOpt).isPresent();
 
     SvgDoc svg = new SvgDoc(svgOpt.get());
     svg.assertRootSvg();
@@ -692,18 +775,22 @@
     assertThat(svg.findText("<iframe src='javascript:alert(1)'></iframe>")).isNotNull();
     assertThat(svg.findText("<img src=x onerror=alert('img-onerror')>")).isNotNull();
     assertThat(svg.findText("<svg onload=alert('svg-onload')>")).isNotNull();
-    assertThat(svg.findText("<foreignObject><iframe src='https://evil.com'></iframe></foreignObject>")).isNotNull();
+    assertThat(
+            svg.findText("<foreignObject><iframe src='https://evil.com'></iframe></foreignObject>"))
+        .isNotNull();
     assertThat(svg.findText("<a href='javascript:alert(1)'>Click Me</a>")).isNotNull();
   }
 
   @Test
   public void testSecurityNoScriptOrIframeInEdgeLabels() {
     String code =
-        "graph TD\n"
-            + "  A -->|\"<script>alert('edge-pipe')</script>\"| B\n"
-            + "  B -- \"<iframe src='http://evil.com'></iframe>\" --> C\n"
-            + "  C == \"<img src=x onerror=alert('thick-edge')>\" ==> D\n"
-            + "  D -. \"<svg onload=alert('dashed-edge')>\" .-> E\n";
+        """
+        graph TD
+          A -->|"<script>alert('edge-pipe')</script>"| B
+          B -- "<iframe src='http://evil.com'></iframe>" --> C
+          C == "<img src=x onerror=alert('thick-edge')>" ==> D
+          D -. "<svg onload=alert('dashed-edge')>" .-> E
+        """;
     SvgDoc svg = render(code);
 
     assertThat(svg.getElementsByTag("script")).isEmpty();
@@ -727,14 +814,16 @@
   @Test
   public void testSecurityNoScriptOrIframeInSubgraphTitles() {
     String code =
-        "graph TD\n"
-            + "  subgraph Sg1 [\"<script>alert('subgraph-title')</script>\"]\n"
-            + "    A[Node A]\n"
-            + "  end\n"
-            + "  subgraph Sg2 [\"<iframe src='javascript:alert(2)'></iframe>\"]\n"
-            + "    B[Node B]\n"
-            + "  end\n"
-            + "  A --> B\n";
+        """
+        graph TD
+          subgraph Sg1 ["<script>alert('subgraph-title')</script>"]
+            A[Node A]
+          end
+          subgraph Sg2 ["<iframe src='javascript:alert(2)'></iframe>"]
+            B[Node B]
+          end
+          A --> B
+        """;
     SvgDoc svg = render(code);
 
     assertThat(svg.getElementsByTag("script")).isEmpty();
@@ -753,14 +842,16 @@
   @Test
   public void testSecurityDirectivesCannotInjectJavascriptUrls() {
     String code =
-        "graph TD\n"
-            + "  A[Node A] --> B[Node B]\n"
-            + "  click A href \"javascript:alert('click-href')\"\n"
-            + "  click B call alert('click-call')\n"
-            + "  click A \"javascript:alert('positional-href')\"\n"
-            + "  style A fill:url(javascript:alert(1))\n"
-            + "  classDef evil fill:red,color:white;\n"
-            + "  linkStyle 0 stroke:red;\n";
+        """
+        graph TD
+          A[Node A] --> B[Node B]
+          click A href "javascript:alert('click-href')"
+          click B call alert('click-call')
+          click A "javascript:alert('positional-href')"
+          style A fill:url(javascript:alert(1))
+          classDef evil fill:red,color:white;
+          linkStyle 0 stroke:red;
+        """;
     SvgDoc svg = render(code);
 
     assertThat(svg.getElementsByTag("a")).isEmpty();
@@ -776,15 +867,17 @@
   @Test
   public void testSecurityXmlBreakoutPayloads() {
     String code =
-        "graph TD\n"
-            + "  A[\"</text></svg><script>alert('breakout')</script><svg><text>\"]\n"
-            + "  B[\"'\"><script>alert('quote-breakout')</script>\"]\n"
-            + "  A --> B\n";
+        """
+        graph TD
+          A["</text></svg><script>alert('breakout')</script><svg><text>"]
+          B["'"><script>alert('quote-breakout')</script>"]
+          A --> B
+        """;
     SvgDoc svg = render(code);
 
     // Verify the document root remains the only SVG element and no script elements were injected
     assertThat(svg.getElementsByTag("script")).isEmpty();
-    assertThat(svg.getElementsByTag("svg").size()).isEqualTo(1);
+    assertThat(svg.getElementsByTag("svg")).hasSize(1);
 
     String raw = SimpleMermaidRenderer.renderToSvg(code).get();
     assertThat(raw).doesNotContain("<script");
@@ -794,25 +887,27 @@
   @Test
   public void testIsolatedSubgraphAlongsideMainDagTree() {
     String code =
-        "graph TD\n"
-            + "    ClientApp[Little Puppy Plays] --> Extras(Sweet Kitten)\n"
-            + "    ClientApp --> Utils(Happy Bunny)\n"
-            + "    \n"
-            + "    Utils --> ServiceDiscovery[Red Apple Berry]\n"
-            + "    Utils --> ModelManager[Yellow Banana Snack]\n"
-            + "    \n"
-            + "    Extras --> Recognition(Fluffy Duckling)\n"
-            + "    \n"
-            + "    Recognition --> SODA(Green Frog Jump)\n"
-            + "    Recognition --> S3(Sunny Daisy Flower)\n"
-            + "    \n"
-            + "    subgraph Play Park Garden\n"
-            + "        Executors(Teddy Bear)\n"
-            + "        Errors(Wooden Blocks)\n"
-            + "        Protos(Toy Wagon)\n"
-            + "    end\n"
-            + "    \n"
-            + "    Recognition -.-> PlayParkGarden\n";
+        """
+        graph TD
+            ClientApp[Little Puppy Plays] --> Extras(Sweet Kitten)
+            ClientApp --> Utils(Happy Bunny)
+           \s
+            Utils --> ServiceDiscovery[Red Apple Berry]
+            Utils --> ModelManager[Yellow Banana Snack]
+           \s
+            Extras --> Recognition(Fluffy Duckling)
+           \s
+            Recognition --> SODA(Green Frog Jump)
+            Recognition --> S3(Sunny Daisy Flower)
+           \s
+            subgraph Play Park Garden
+                Executors(Teddy Bear)
+                Errors(Wooden Blocks)
+                Protos(Toy Wagon)
+            end
+           \s
+            Recognition -.-> PlayParkGarden
+        """;
     SvgDoc svg = render(code);
 
     // Verify all nodes and subgraph title exist
@@ -830,7 +925,8 @@
     assertThat(svg.findText("Sunny Daisy Flower")).isNotNull();
     assertThat(svg.findText("PlayParkGarden")).isNotNull();
 
-    // Verify vertical stack in Play Park Garden subgraph (Teddy Bear above Wooden Blocks above Toy Wagon)
+    // Verify vertical stack in Play Park Garden subgraph (Teddy Bear above Wooden Blocks above Toy
+    // Wagon)
     Element executorsText = svg.findText("Teddy Bear");
     Element errorsText = svg.findText("Wooden Blocks");
     Element protoText = svg.findText("Toy Wagon");
@@ -850,20 +946,22 @@
   @Test
   public void testMultiNodeChainingWithAmpersand() {
     String code =
-        "graph TD\n"
-            + "    A[Little Star] --> CheckJDAA{Is Puppy Sleepy?}\n"
-            + "    CheckJDAA -- No --> InstallJDA[Play With Soft Ball]\n"
-            + "    InstallJDA --> CheckJDAA\n"
-            + "    CheckJDAA -- Yes --> B{Wants Sweet Cookie?}\n"
-            + "    B -- Yes --> C[Drink Warm Milk Cup]\n"
-            + "    B -- No --> D[Sing Happy Lullaby]\n"
-            + "    D --> E[Cuddle Warm Blanket]\n"
-            + "    D --> F[Hug Fluffy Panda]\n"
-            + "    D --> G[Close Shiny Eyes]\n"
-            + "    E & F & G --> H[Sweet Dreams Forest]\n"
-            + "    C & H --> I[Gentle Good Night]\n"
-            + "    I --> J[Sleep Until Morning]\n"
-            + "    J --> K[Wake Up Happy Sun]\n";
+        """
+        graph TD
+            A[Little Star] --> CheckJDAA{Is Puppy Sleepy?}
+            CheckJDAA -- No --> InstallJDA[Play With Soft Ball]
+            InstallJDA --> CheckJDAA
+            CheckJDAA -- Yes --> B{Wants Sweet Cookie?}
+            B -- Yes --> C[Drink Warm Milk Cup]
+            B -- No --> D[Sing Happy Lullaby]
+            D --> E[Cuddle Warm Blanket]
+            D --> F[Hug Fluffy Panda]
+            D --> G[Close Shiny Eyes]
+            E & F & G --> H[Sweet Dreams Forest]
+            C & H --> I[Gentle Good Night]
+            I --> J[Sleep Until Morning]
+            J --> K[Wake Up Happy Sun]
+        """;
     SvgDoc svg = render(code);
 
     // Verify all nodes exist
@@ -909,21 +1007,24 @@
     assertThat(multiDoc.findText("B")).isNotNull();
     assertThat(multiDoc.findText("C")).isNotNull();
     assertThat(multiDoc.findText("D")).isNotNull();
-    assertThat(multiDoc.getElementsByTag("path").size()).isEqualTo(5); // 1 marker path in <defs> + 4 edge paths
+    assertThat(multiDoc.getElementsByTag("path"))
+        .hasSize(5); // 1 marker path in <defs> + 4 edge paths
   }
 
   @Test
   public void testSubgraphDirectionOverrideWithCrossEdges() {
     String code =
-        "graph TD\n"
-            + "  subgraph Castle [\"Toy Castle\"]\n"
-            + "    direction LR\n"
-            + "    A[Happy Bear] --> B[Silly Goose]\n"
-            + "  end\n"
-            + "  subgraph Garden [\"Flower Garden\"]\n"
-            + "    C[Sunny Daisy]\n"
-            + "  end\n"
-            + "  B --> C\n";
+        """
+        graph TD
+          subgraph Castle ["Toy Castle"]
+            direction LR
+            A[Happy Bear] --> B[Silly Goose]
+          end
+          subgraph Garden ["Flower Garden"]
+            C[Sunny Daisy]
+          end
+          B --> C
+        """;
     SvgDoc doc = render(code);
     assertThat(doc.findText("Toy Castle")).isNotNull();
     assertThat(doc.findText("Flower Garden")).isNotNull();
@@ -935,20 +1036,22 @@
   @Test
   public void testNestedSubgraphsWithLabeledInterChildEdge() {
     String code =
-        "graph LR\n"
-            + "  subgraph ToyBox [\"Big Toy Box\"]\n"
-            + "    subgraph PuzzleA [\"Puppy Puzzle\"]\n"
-            + "      A[Little Dog]\n"
-            + "    end\n"
-            + "    subgraph PuzzleB [\"Kitten Puzzle\"]\n"
-            + "      B[Little Cat]\n"
-            + "    end\n"
-            + "    A -->|Friendly Meow| B\n"
-            + "  end\n"
-            + "  subgraph BedTime [\"Sleepy Pillow\"]\n"
-            + "    C[Cozy Blanket]\n"
-            + "  end\n"
-            + "  B -->|Soft Hug| C\n";
+        """
+        graph LR
+          subgraph ToyBox ["Big Toy Box"]
+            subgraph PuzzleA ["Puppy Puzzle"]
+              A[Little Dog]
+            end
+            subgraph PuzzleB ["Kitten Puzzle"]
+              B[Little Cat]
+            end
+            A -->|Friendly Meow| B
+          end
+          subgraph BedTime ["Sleepy Pillow"]
+            C[Cozy Blanket]
+          end
+          B -->|Soft Hug| C
+        """;
     SvgDoc doc = render(code);
     assertThat(doc.findText("Big Toy Box")).isNotNull();
     assertThat(doc.findText("Puppy Puzzle")).isNotNull();
@@ -964,18 +1067,20 @@
   @Test
   public void testNestedSubgraphsVerticalWithCrossEdgesAndEmptySubgraphs() {
     String code =
-        "graph TD\n"
-            + "  subgraph WonderLand [\"Magic Wonderland\"]\n"
-            + "    subgraph EmptyBox [\"Empty Treasure Chest\"]\n"
-            + "    end\n"
-            + "    subgraph ZoneA [\"Butterfly Valley\"]\n"
-            + "      A[Shiny Butterfly]\n"
-            + "    end\n"
-            + "    subgraph ZoneB [\"Rainbow Hill\"]\n"
-            + "      B[Glowing Rainbow]\n"
-            + "    end\n"
-            + "    B -->|Sweet Melody| A\n"
-            + "  end\n";
+        """
+        graph TD
+          subgraph WonderLand ["Magic Wonderland"]
+            subgraph EmptyBox ["Empty Treasure Chest"]
+            end
+            subgraph ZoneA ["Butterfly Valley"]
+              A[Shiny Butterfly]
+            end
+            subgraph ZoneB ["Rainbow Hill"]
+              B[Glowing Rainbow]
+            end
+            B -->|Sweet Melody| A
+          end
+        """;
     SvgDoc doc = render(code);
     assertThat(doc.findText("Magic Wonderland")).isNotNull();
     assertThat(doc.findText("Empty Treasure Chest")).isNotNull();
@@ -989,11 +1094,13 @@
   @Test
   public void testSkipLayerBypassWithDummyNodesTD() {
     String code =
-        "graph TD\n"
-            + "  A[Teddy Bear] -->|Blue Balloon| B[Silly Monkey]\n"
-            + "  A -->|Red Apple| C[Happy Puppy]\n"
-            + "  B --> C\n"
-            + "  C --> D[Little Kitten]\n";
+        """
+        graph TD
+          A[Teddy Bear] -->|Blue Balloon| B[Silly Monkey]
+          A -->|Red Apple| C[Happy Puppy]
+          B --> C
+          C --> D[Little Kitten]
+        """;
     SvgDoc doc = render(code);
     assertThat(doc.findText("Teddy Bear")).isNotNull();
     assertThat(doc.findText("Silly Monkey")).isNotNull();
@@ -1006,11 +1113,13 @@
   @Test
   public void testSkipLayerBypassWithDummyNodesLR() {
     String code =
-        "graph LR\n"
-            + "  A[Teddy Bear] -->|Blue Balloon| B[Silly Monkey]\n"
-            + "  A -->|Red Apple| C[Happy Puppy]\n"
-            + "  B --> C\n"
-            + "  C --> D[Little Kitten]\n";
+        """
+        graph LR
+          A[Teddy Bear] -->|Blue Balloon| B[Silly Monkey]
+          A -->|Red Apple| C[Happy Puppy]
+          B --> C
+          C --> D[Little Kitten]
+        """;
     SvgDoc doc = render(code);
     assertThat(doc.findText("Teddy Bear")).isNotNull();
     assertThat(doc.findText("Silly Monkey")).isNotNull();
@@ -1023,23 +1132,25 @@
   @Test
   public void testCompoundSubgraphAndStandaloneNodesLayoutWithStyles() {
     String code =
-        "graph LR\n"
-            + "  subgraph CastleBox [\"Play Castle\"]\n"
-            + "    direction TB\n"
-            + "    ToyA[Magic Wand] <--> ToyB[Cozy Teddy]\n"
-            + "  end\n"
-            + "  subgraph GardenBox [\"Flower Garden\"]\n"
-            + "    ToyC[Pink Blossom] --> ToyD[Sweet Daisy]\n"
-            + "  end\n"
-            + "  ToyB --> ToyC\n"
-            + "  ToyE[Happy Butterfly] --> ToyB\n"
-            + "  style CastleBox fill:#e3f2fd,stroke:#1e88e5\n"
-            + "  style GardenBox fill:rgb(240,250,240),stroke:#43a047\n"
-            + "  style ToyE fill:hsl(120,50%,90%),stroke:blue\n"
-            + "  style ToyA fill:rgba(255,255,255,0.8),stroke:purple\n"
-            + "  style ToyC fill:#ffb300,stroke:#333333\n"
-            + "  style \"\" fill:#fff\n"
-            + "  style NonExistent fill:#fff\n";
+        """
+        graph LR
+          subgraph CastleBox ["Play Castle"]
+            direction TB
+            ToyA[Magic Wand] <--> ToyB[Cozy Teddy]
+          end
+          subgraph GardenBox ["Flower Garden"]
+            ToyC[Pink Blossom] --> ToyD[Sweet Daisy]
+          end
+          ToyB --> ToyC
+          ToyE[Happy Butterfly] --> ToyB
+          style CastleBox fill:#e3f2fd,stroke:#1e88e5
+          style GardenBox fill:rgb(240,250,240),stroke:#43a047
+          style ToyE fill:hsl(120,50%,90%),stroke:blue
+          style ToyA fill:rgba(255,255,255,0.8),stroke:purple
+          style ToyC fill:#ffb300,stroke:#333333
+          style "" fill:#fff
+          style NonExistent fill:#fff
+        """;
     SvgDoc doc = render(code);
     assertThat(doc.findText("Play Castle")).isNotNull();
     assertThat(doc.findText("Flower Garden")).isNotNull();
@@ -1053,18 +1164,20 @@
   @Test
   public void testStyledCustomShapes() {
     String code =
-        "graph TD\n"
-            + "  N1((Sun Ball)) --> N2{Magic Gem}\n"
-            + "  N2 --> N3{{Toy Boat}}\n"
-            + "  N3 --> N4[(Toy Castle)]\n"
-            + "  N4 --> N5>Sweet Candy]\n"
-            + "  N5 --> N6[[Puppy House]]\n"
-            + "  style N1 fill:#ffecb3,stroke:#ffa000\n"
-            + "  style N2 fill:#e1bee7,stroke:#8e24aa\n"
-            + "  style N3 fill:#c8e6c9,stroke:#388e3c\n"
-            + "  style N4 fill:#b2ebf2,stroke:#00838f\n"
-            + "  style N5 fill:#ffcdd2,stroke:#c62828\n"
-            + "  style N6 fill:#d1c4e9,stroke:#512da8\n";
+        """
+        graph TD
+          N1((Sun Ball)) --> N2{Magic Gem}
+          N2 --> N3{{Toy Boat}}
+          N3 --> N4[(Toy Castle)]
+          N4 --> N5>Sweet Candy]
+          N5 --> N6[[Puppy House]]
+          style N1 fill:#ffecb3,stroke:#ffa000
+          style N2 fill:#e1bee7,stroke:#8e24aa
+          style N3 fill:#c8e6c9,stroke:#388e3c
+          style N4 fill:#b2ebf2,stroke:#00838f
+          style N5 fill:#ffcdd2,stroke:#c62828
+          style N6 fill:#d1c4e9,stroke:#512da8
+        """;
     SvgDoc doc = render(code);
     assertThat(doc.findText("Sun Ball")).isNotNull();
     assertThat(doc.findText("Magic Gem")).isNotNull();
@@ -1077,10 +1190,12 @@
   @Test
   public void testSingleUnitCompoundComponent() {
     String code =
-        "graph TD\n"
-            + "  subgraph SoloBox [\"Secret Clubhouse\"]\n"
-            + "    KidA[Little Star] --> KidB[Bright Moon]\n"
-            + "  end\n";
+        """
+        graph TD
+          subgraph SoloBox ["Secret Clubhouse"]
+            KidA[Little Star] --> KidB[Bright Moon]
+          end
+        """;
     SvgDoc doc = render(code);
     assertThat(doc.findText("Secret Clubhouse")).isNotNull();
     assertThat(doc.findText("Little Star")).isNotNull();
@@ -1090,17 +1205,19 @@
   @Test
   public void testSequentialSubgraphsWithoutInternalDag() {
     String code =
-        "graph TD\n"
-            + "  subgraph VertBox [\"Stacking Blocks\"]\n"
-            + "    BoxA[Red Block]\n"
-            + "    BoxB[Blue Block]\n"
-            + "    BoxC[Green Block]\n"
-            + "  end\n"
-            + "  subgraph HorizBox [\"Toy Train\"]\n"
-            + "    direction LR\n"
-            + "    CarA[Train Engine]\n"
-            + "    CarB[Train Caboose]\n"
-            + "  end\n";
+        """
+        graph TD
+          subgraph VertBox ["Stacking Blocks"]
+            BoxA[Red Block]
+            BoxB[Blue Block]
+            BoxC[Green Block]
+          end
+          subgraph HorizBox ["Toy Train"]
+            direction LR
+            CarA[Train Engine]
+            CarB[Train Caboose]
+          end
+        """;
     SvgDoc doc = render(code);
     assertThat(doc.findText("Stacking Blocks")).isNotNull();
     assertThat(doc.findText("Toy Train")).isNotNull();
@@ -1109,20 +1226,22 @@
   @Test
   public void testSequentialSubgraphsWithLabels() {
     String code =
-        "graph TD\n"
-            + "  subgraph VertBox [\"Stacking Blocks\"]\n"
-            + "    BoxA[Red Block]\n"
-            + "    BoxB[Blue Block]\n"
-            + "  end\n"
-            + "  subgraph HorizBox [\"Toy Train\"]\n"
-            + "    direction LR\n"
-            + "    CarA[Train Engine]\n"
-            + "    CarB[Train Caboose]\n"
-            + "  end\n"
-            + "  BoxA -->|Stack On| BoxB\n"
-            + "  CarA -->|Pull Car| CarB\n"
-            + "  style BoxA fill:#112233;stroke:#445566\n"
-            + "  style BoxB fill:#112233,stroke:#445566\n";
+        """
+        graph TD
+          subgraph VertBox ["Stacking Blocks"]
+            BoxA[Red Block]
+            BoxB[Blue Block]
+          end
+          subgraph HorizBox ["Toy Train"]
+            direction LR
+            CarA[Train Engine]
+            CarB[Train Caboose]
+          end
+          BoxA -->|Stack On| BoxB
+          CarA -->|Pull Car| CarB
+          style BoxA fill:#112233;stroke:#445566
+          style BoxB fill:#112233,stroke:#445566
+        """;
     SvgDoc doc = render(code);
     assertThat(doc.findText("Stacking Blocks")).isNotNull();
     assertThat(doc.findText("Toy Train")).isNotNull();
@@ -1131,18 +1250,20 @@
   @Test
   public void testMultiLayerCompoundComponent() {
     String code =
-        "graph LR\n"
-            + "  subgraph Box1 [\"First Box\"]\n"
-            + "    A[Puppy Dog]\n"
-            + "  end\n"
-            + "  subgraph Box2 [\"Second Box\"]\n"
-            + "    B[Kitty Cat]\n"
-            + "  end\n"
-            + "  subgraph Box3 [\"Third Box\"]\n"
-            + "    C[Bunny Rabbit]\n"
-            + "  end\n"
-            + "  A --> B\n"
-            + "  B --> C\n";
+        """
+        graph LR
+          subgraph Box1 ["First Box"]
+            A[Puppy Dog]
+          end
+          subgraph Box2 ["Second Box"]
+            B[Kitty Cat]
+          end
+          subgraph Box3 ["Third Box"]
+            C[Bunny Rabbit]
+          end
+          A --> B
+          B --> C
+        """;
     SvgDoc doc = render(code);
     assertThat(doc.findText("First Box")).isNotNull();
     assertThat(doc.findText("Second Box")).isNotNull();
@@ -1152,19 +1273,21 @@
   @Test
   public void testTripleNestedSubgraphsWithCrossChildEdges() {
     String code =
-        "graph TD\n"
-            + "  subgraph OuterCastle [\"Giant Castle\"]\n"
-            + "    subgraph MidTower [\"High Tower\"]\n"
-            + "      subgraph InnerRoom [\"Secret Room\"]\n"
-            + "        Gem[Magic Ruby]\n"
-            + "      end\n"
-            + "    end\n"
-            + "    subgraph SecondTower [\"Low Tower\"]\n"
-            + "      OtherGem[Shiny Emerald]\n"
-            + "    end\n"
-            + "    Gem -->|Sparkle Magic| OtherGem\n"
-            + "  end\n"
-            + "  Dragon[Friendly Dragon] --> Gem\n";
+        """
+        graph TD
+          subgraph OuterCastle ["Giant Castle"]
+            subgraph MidTower ["High Tower"]
+              subgraph InnerRoom ["Secret Room"]
+                Gem[Magic Ruby]
+              end
+            end
+            subgraph SecondTower ["Low Tower"]
+              OtherGem[Shiny Emerald]
+            end
+            Gem -->|Sparkle Magic| OtherGem
+          end
+          Dragon[Friendly Dragon] --> Gem
+        """;
     SvgDoc doc = render(code);
     assertThat(doc.findText("Giant Castle")).isNotNull();
     assertThat(doc.findText("High Tower")).isNotNull();
@@ -1179,13 +1302,15 @@
   @Test
   public void testDecisionTreeBranchingWithFeedbackLoopAndChildrenWords() {
     String code =
-        "graph TD\n"
-            + "  A[Little Bunny Play] --> B{Choose Sweet Snack}\n"
-            + "  B -->|Crisp Red Apple| C[Happy Bunny Chew]\n"
-            + "  B -->|Sweet Yellow Banana| D[Joyful Bunny Hop]\n"
-            + "  B -->|Crunchy Orange Carrot| E[Cheerful Bunny Munch]\n"
-            + "  E -->|Ask For More Treats| B\n"
-            + "  E -->|Tired Little Nap| F[Sleepy Cozy Blanket]\n";
+        """
+        graph TD
+          A[Little Bunny Play] --> B{Choose Sweet Snack}
+          B -->|Crisp Red Apple| C[Happy Bunny Chew]
+          B -->|Sweet Yellow Banana| D[Joyful Bunny Hop]
+          B -->|Crunchy Orange Carrot| E[Cheerful Bunny Munch]
+          E -->|Ask For More Treats| B
+          E -->|Tired Little Nap| F[Sleepy Cozy Blanket]
+        """;
     SvgDoc doc = render(code);
     assertThat(doc.findText("Little Bunny Play")).isNotNull();
     assertThat(doc.findText("Choose Sweet Snack")).isNotNull();
@@ -1216,7 +1341,7 @@
     assertThat(doc.findText(longLabel)).isNotNull();
 
     List<Element> rects = doc.getElementsByTag("rect");
-    assertThat(rects.size()).isEqualTo(1);
+    assertThat(rects).hasSize(1);
     double rectWidth = Double.parseDouble(rects.get(0).getAttribute("width"));
     double expectedMin = longLabel.length() * 7.5;
     assertThat(rectWidth).isGreaterThan(expectedMin);
@@ -1226,21 +1351,23 @@
   @Test
   public void testNestedSubgraphWithSiblingNodesAndCrossLayerEdges() {
     String code =
-        "graph TD\n"
-            + "  subgraph ToyBox [\"Big Toy Box\"]\n"
-            + "    A[Magic Wand] --> B[Golden Crown]\n"
-            + "    B --> C[Shiny Sparkles]\n"
-            + "    D[Toy Train] --> E{Has Train Track?}\n"
-            + "    E -->|Yes| F[Start Train Engine]\n"
-            + "    subgraph TrainCars [\"Little Train Cars\"]\n"
-            + "      F --> G[Red Caboose]\n"
-            + "      G --> H[Blue Engine]\n"
-            + "    end\n"
-            + "  end\n"
-            + "  subgraph Playroom [\"Sunny Playroom\"]\n"
-            + "    Target[Happy Child Playing]\n"
-            + "  end\n"
-            + "  H --> Target\n";
+        """
+        graph TD
+          subgraph ToyBox ["Big Toy Box"]
+            A[Magic Wand] --> B[Golden Crown]
+            B --> C[Shiny Sparkles]
+            D[Toy Train] --> E{Has Train Track?}
+            E -->|Yes| F[Start Train Engine]
+            subgraph TrainCars ["Little Train Cars"]
+              F --> G[Red Caboose]
+              G --> H[Blue Engine]
+            end
+          end
+          subgraph Playroom ["Sunny Playroom"]
+            Target[Happy Child Playing]
+          end
+          H --> Target
+        """;
     SvgDoc doc = render(code);
 
     assertThat(doc.findText("Big Toy Box")).isNotNull();
@@ -1268,12 +1395,14 @@
   @Test
   public void testCylinderShapeWithAlapCompactionAndBackEdgeClearance() {
     String code =
-        "graph TD\n"
-            + "  A[(\"Honey Pot <br> Sweet & Yummy\")] -->|Morning Buzz| B[Busy Little Bumblebee]\n"
-            + "  B -->|Happy Flight| C[Flower Garden Patch]\n"
-            + "  D[Playful Garden Snail] -->|Slow Crawl| C\n"
-            + "  C -->|Gather Nectar| A\n"
-            + "  C -->|Pollinate Plants| E[Bright Sunflower]\n";
+        """
+        graph TD
+          A[("Honey Pot <br> Sweet & Yummy")] -->|Morning Buzz| B[Busy Little Bumblebee]
+          B -->|Happy Flight| C[Flower Garden Patch]
+          D[Playful Garden Snail] -->|Slow Crawl| C
+          C -->|Gather Nectar| A
+          C -->|Pollinate Plants| E[Bright Sunflower]
+        """;
     SvgDoc doc = render(code);
 
     assertThat(doc.findText("Honey Pot")).isNotNull();
@@ -1301,7 +1430,8 @@
     for (Element p : paths) {
       String d = p.getAttribute("d");
       if (d.contains(" C ")) {
-        for (String part : Splitter.onPattern("[,\\s]+").omitEmptyStrings().split(d)) {
+        for (String part :
+            Splitter.on(java.util.regex.Pattern.compile("[,\\s]+")).omitEmptyStrings().split(d)) {
           try {
             double val = Double.parseDouble(part);
             if (val > dRight) {
@@ -1320,23 +1450,25 @@
   @Test
   public void testSubgraphEdgeWithDirectionOverrideAndDynamicLabelSpacing() {
     String code =
-        "flowchart TD\n"
-            + "  subgraph StoryOne [\"Teddy Bear Adventure\"]\n"
-            + "    direction LR\n"
-            + "    P1[Cozy Blanket] ---|Soft Fluffy Hug| P2[Sweet Dream]\n"
-            + "    P2 ---|Gentle Night Song| P3[Morning Sun]\n"
-            + "  end\n"
-            + "  subgraph StoryTwo [\"Puppy Playground\"]\n"
-            + "    direction LR\n"
-            + "    Q1[Rubber Ball] ---|Happy Bouncy Leap| Q2[Flying Frisbee]\n"
-            + "    Q2 ---|Wagging Tail Jump| Q3[Green Lawn]\n"
-            + "  end\n"
-            + "  StoryOne ==>|Wake Up Early| StoryTwo\n";
+        """
+        flowchart TD
+          subgraph StoryOne ["Teddy Bear Adventure"]
+            direction LR
+            P1[Cozy Blanket] ---|Soft Fluffy Hug| P2[Sweet Dream]
+            P2 ---|Gentle Night Song| P3[Morning Sun]
+          end
+          subgraph StoryTwo ["Puppy Playground"]
+            direction LR
+            Q1[Rubber Ball] ---|Happy Bouncy Leap| Q2[Flying Frisbee]
+            Q2 ---|Wagging Tail Jump| Q3[Green Lawn]
+          end
+          StoryOne ==>|Wake Up Early| StoryTwo
+        """;
     SvgDoc doc = render(code);
 
     // 1. Subgraph container layout and node containment checks
     List<SvgDoc.Rect2D> sgs = doc.getSubgraphBoundingBoxes();
-    assertThat(sgs.size()).isEqualTo(2);
+    assertThat(sgs).hasSize(2);
     SvgDoc.Rect2D sg1 = sgs.get(0);
     SvgDoc.Rect2D sg2 = sgs.get(1);
 
@@ -1344,7 +1476,7 @@
     assertThat(sg1.bottom()).isLessThan(sg2.y);
 
     List<SvgDoc.Rect2D> nodes = doc.getNodeBoundingBoxes();
-    assertThat(nodes.size()).isEqualTo(6);
+    assertThat(nodes).hasSize(6);
     for (int i = 0; i < 3; i++) {
       assertThat(sg1.contains(nodes.get(i), 10.0)).isTrue();
     }
@@ -1354,7 +1486,7 @@
 
     // 2. Subgraph connecting edge geometry
     List<Element> lines = doc.getElementsByTag("line");
-    assertThat(lines.size()).isEqualTo(1);
+    assertThat(lines).hasSize(1);
     Element seLine = lines.get(0);
     double lx1 = Double.parseDouble(seLine.getAttribute("x1"));
     double ly1 = Double.parseDouble(seLine.getAttribute("y1"));
@@ -1367,7 +1499,7 @@
 
     // 3. Intra-subgraph horizontal edge paths
     List<Element> paths = doc.getEdgePaths();
-    assertThat(paths.size()).isEqualTo(4);
+    assertThat(paths).hasSize(4);
     for (Element p : paths) {
       String d = p.getAttribute("d");
       assertThat(d).startsWith("M ");
@@ -1377,17 +1509,19 @@
   @Test
   public void testIsolatedSubgraphInHorizontalGraph() {
     String code =
-        "graph LR\n"
-            + "  subgraph Garden [\"Flower Garden\"]\n"
-            + "    A[Bright Tulip]\n"
-            + "    B[Daisy Flower]\n"
-            + "  end\n";
+        """
+        graph LR
+          subgraph Garden ["Flower Garden"]
+            A[Bright Tulip]
+            B[Daisy Flower]
+          end
+        """;
     SvgDoc doc = render(code);
 
     List<SvgDoc.Rect2D> sgs = doc.getSubgraphBoundingBoxes();
-    assertThat(sgs.size()).isEqualTo(1);
+    assertThat(sgs).hasSize(1);
     List<SvgDoc.Rect2D> nodes = doc.getNodeBoundingBoxes();
-    assertThat(nodes.size()).isEqualTo(2);
+    assertThat(nodes).hasSize(2);
     assertThat(sgs.get(0).contains(nodes.get(0), 10.0)).isTrue();
     assertThat(sgs.get(0).contains(nodes.get(1), 10.0)).isTrue();
   }
@@ -1395,20 +1529,22 @@
   @Test
   public void testNestedSubgraphsWithInternalSubgraphEdgeAndInheritedDirection() {
     String code =
-        "graph TD\n"
-            + "  subgraph MainBox [\"Toy Warehouse\"]\n"
-            + "    direction LR\n"
-            + "    subgraph BoxOne [\"Teddy Room\"]\n"
-            + "      A[Brown Bear]\n"
-            + "    end\n"
-            + "    subgraph BoxTwo [\"Puppy Room\"]\n"
-            + "      B[Happy Dog]\n"
-            + "    end\n"
-            + "    BoxOne --> BoxTwo\n"
-            + "  end\n";
+        """
+        graph TD
+          subgraph MainBox ["Toy Warehouse"]
+            direction LR
+            subgraph BoxOne ["Teddy Room"]
+              A[Brown Bear]
+            end
+            subgraph BoxTwo ["Puppy Room"]
+              B[Happy Dog]
+            end
+            BoxOne --> BoxTwo
+          end
+        """;
     SvgDoc doc = render(code);
 
     List<SvgDoc.Rect2D> sgs = doc.getSubgraphBoundingBoxes();
-    assertThat(sgs.size()).isEqualTo(3);
+    assertThat(sgs).hasSize(3);
   }
 }
diff --git a/javatests/com/google/gitiles/doc/SvgDoc.java b/javatests/com/google/gitiles/doc/SvgDoc.java
index 0463ee7..0384d55 100644
--- a/javatests/com/google/gitiles/doc/SvgDoc.java
+++ b/javatests/com/google/gitiles/doc/SvgDoc.java
@@ -18,11 +18,12 @@
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
 import java.io.StringReader;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Optional;
+import java.util.regex.Pattern;
 import javax.annotation.Nullable;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
@@ -32,13 +33,11 @@
 import org.w3c.dom.NodeList;
 import org.xml.sax.InputSource;
 
-/**
- * Shared DOM and geometric assertion helper for Mermaid SVG test suites.
- */
+/** Shared DOM and geometric assertion helper for Mermaid SVG test suites. */
 public class SvgDoc {
 
-  public static final List<String> DANGEROUS_TAGS =
-      Arrays.asList(
+  public static final ImmutableList<String> DANGEROUS_TAGS =
+      ImmutableList.of(
           "script",
           "iframe",
           "foreignObject",
@@ -84,18 +83,19 @@
    */
   public static SvgDoc render(String mermaidCode) {
     Optional<String> svgOpt = SimpleMermaidRenderer.renderToSvg(mermaidCode);
-    assertThat(svgOpt.isPresent()).isTrue();
+    assertThat(svgOpt).isPresent();
     SvgDoc doc = new SvgDoc(svgOpt.get());
     doc.assertAllInvariants();
     return doc;
   }
 
   /**
-   * Renders the given Mermaid diagram code without asserting collision invariants (e.g. for malformed tests).
+   * Renders the given Mermaid diagram code without asserting collision invariants (e.g. for
+   * malformed tests).
    */
   public static SvgDoc renderRaw(String mermaidCode) {
     Optional<String> svgOpt = SimpleMermaidRenderer.renderToSvg(mermaidCode);
-    assertThat(svgOpt.isPresent()).isTrue();
+    assertThat(svgOpt).isPresent();
     return new SvgDoc(svgOpt.get());
   }
 
@@ -120,7 +120,7 @@
 
   public void assertDefs() {
     List<Element> defs = getElementsByTag("defs");
-    assertThat(defs.size()).isEqualTo(1);
+    assertThat(defs).hasSize(1);
     Element def = defs.get(0);
     NodeList markers = def.getElementsByTagName("marker");
     assertThat(markers.getLength()).isEqualTo(1);
@@ -146,8 +146,8 @@
     NodeList nl = doc.getElementsByTagName(tagName);
     for (int i = 0; i < nl.getLength(); i++) {
       Node n = nl.item(i);
-      if (n instanceof Element) {
-        list.add((Element) n);
+      if (n instanceof Element element) {
+        list.add(element);
       }
     }
     return list;
@@ -156,7 +156,7 @@
   public List<Element> getEdgePaths() {
     List<Element> list = new ArrayList<>();
     for (Element p : getElementsByTag("path")) {
-      if (!"M 0 1.5 L 10 5 L 0 8.5 z".equals(p.getAttribute("d"))) {
+      if (!p.getAttribute("d").equals("M 0 1.5 L 10 5 L 0 8.5 z")) {
         list.add(p);
       }
     }
@@ -166,14 +166,15 @@
   public List<Element> findSubgraphRects() {
     List<Element> list = new ArrayList<>();
     for (Element r : getElementsByTag("rect")) {
-      if ("4,4".equals(r.getAttribute("stroke-dasharray"))) {
+      if (r.getAttribute("stroke-dasharray").equals("4,4")) {
         list.add(r);
       }
     }
     return list;
   }
 
-  public @Nullable Element findPolygonWithVertices(int count) {
+  @Nullable
+  public Element findPolygonWithVertices(int count) {
     for (Element p : getElementsByTag("polygon")) {
       String pts = p.getAttribute("points").trim();
       if (!pts.isEmpty() && pts.split("\\s+").length == count) {
@@ -183,11 +184,14 @@
     return null;
   }
 
-  public @Nullable Element findText(String text) {
+  @Nullable
+  public Element findText(String text) {
     String expected = text.replace("\0", "").trim();
     for (Element t : getElementsByTag("text")) {
       String full = t.getTextContent().trim().replaceAll("\\s+", " ");
-      if (expected.equals(full) || expected.equals(t.getTextContent().trim()) || full.contains(expected)) {
+      if (expected.equals(full)
+          || expected.equals(t.getTextContent().trim())
+          || full.contains(expected)) {
         return t;
       }
     }
@@ -267,7 +271,7 @@
     for (Element r : getElementsByTag("rect")) {
       String dash = r.getAttribute("stroke-dasharray");
       String opacity = r.getAttribute("fill-opacity");
-      if ("4,4".equals(dash) || "0.95".equals(opacity)) {
+      if (dash.equals("4,4") || opacity.equals("0.95")) {
         continue;
       }
       double x = Double.parseDouble(r.getAttribute("x"));
@@ -285,9 +289,11 @@
     for (Element p : getElementsByTag("polygon")) {
       String pts = p.getAttribute("points").trim();
       if (!pts.isEmpty()) {
-        double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE;
-        double maxX = Double.MIN_VALUE, maxY = Double.MIN_VALUE;
-        for (String pair : Splitter.onPattern("\\s+").omitEmptyStrings().split(pts)) {
+        double minX = Double.MAX_VALUE;
+        double minY = Double.MAX_VALUE;
+        double maxX = Double.MIN_VALUE;
+        double maxY = Double.MIN_VALUE;
+        for (String pair : Splitter.on(Pattern.compile("\\s+")).omitEmptyStrings().split(pts)) {
           List<String> xy = Splitter.on(',').splitToList(pair);
           if (xy.size() == 2) {
             double px = Double.parseDouble(xy.get(0));
@@ -309,7 +315,7 @@
   public List<Rect2D> getEdgeLabelBadgeBoundingBoxes() {
     List<Rect2D> list = new ArrayList<>();
     for (Element r : getElementsByTag("rect")) {
-      if ("0.95".equals(r.getAttribute("fill-opacity"))) {
+      if (r.getAttribute("fill-opacity").equals("0.95")) {
         double x = Double.parseDouble(r.getAttribute("x"));
         double y = Double.parseDouble(r.getAttribute("y"));
         double w = Double.parseDouble(r.getAttribute("width"));
@@ -323,7 +329,7 @@
   public List<Rect2D> getSubgraphBoundingBoxes() {
     List<Rect2D> list = new ArrayList<>();
     for (Element r : getElementsByTag("rect")) {
-      if ("4,4".equals(r.getAttribute("stroke-dasharray"))) {
+      if (r.getAttribute("stroke-dasharray").equals("4,4")) {
         double x = Double.parseDouble(r.getAttribute("x"));
         double y = Double.parseDouble(r.getAttribute("y"));
         double w = Double.parseDouble(r.getAttribute("width"));
@@ -340,7 +346,7 @@
       for (int j = i + 1; j < nodes.size(); j++) {
         Rect2D a = nodes.get(i);
         Rect2D b = nodes.get(j);
-        assertWithMessage("Node overlap detected between " + a + " and " + b)
+        assertWithMessage("Node overlap detected between %s and %s", a, b)
             .that(a.overlaps(b, 2.0))
             .isFalse();
       }
@@ -352,7 +358,7 @@
     List<Rect2D> labels = getEdgeLabelBadgeBoundingBoxes();
     for (Rect2D badge : labels) {
       for (Rect2D node : nodes) {
-        assertWithMessage("Edge label badge " + badge + " overlaps node " + node)
+        assertWithMessage("Edge label badge %s overlaps node %s", badge, node)
             .that(badge.overlaps(node, 2.0))
             .isFalse();
       }
@@ -367,7 +373,7 @@
         Rect2D b = sgs.get(j);
         boolean oneContainsOther = a.contains(b, 0) || b.contains(a, 0);
         if (!oneContainsOther) {
-          assertWithMessage("Sibling subgraphs overlap: " + a + " and " + b)
+          assertWithMessage("Sibling subgraphs overlap: %s and %s", a, b)
               .that(a.overlaps(b, 2.0))
               .isFalse();
         }